From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../plain/index.html | 505 +++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html (limited to 'cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html') diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html new file mode 100644 index 00000000..d6ad849d --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html @@ -0,0 +1,505 @@ +/** \file admin_executor_service.cpp + * Admin Executor Service (AES) + * + * $Id: admin_executor_service.cpp,v 1.10 2001/06/27 08:35:13 lecroart Exp $ + * + */ + +/* Copyright, 2000 Nevrax Ltd. + * + * This file is part of NEVRAX NeL Network Services. + * NEVRAX NeL Network Services is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * NEVRAX NeL Network Services is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEVRAX NeL Network Services; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include +#include + +#include "nel/misc/types_nl.h" + +#ifdef NL_OS_WINDOWS +#include +#else +#include +#endif + +#include +#include + +#include "nel/misc/debug.h" +#include "nel/misc/config_file.h" +#include "nel/misc/thread.h" +#include "nel/misc/command.h" + +#include "nel/net/service.h" +#include "nel/net/net_manager.h" + +#ifdef NL_OS_WINDOWS +#define getcwd _getcwd +#define chdir _chdir +#endif + + +using namespace std; +using namespace NLMISC; +using namespace NLNET; + + + +struct CService +{ + CService(TSockId s) : SockId(s), Id(NextId++), Ready(false) { } + + TSockId SockId; /// connection to the service + uint32 Id; /// uint32 to identify the service + string AliasName; /// alias of the service used in the AES and AS to find him (unique per AES) + string ShortName; /// name of the service in short format ("NS" for example) + string LongName; /// name of the service in long format ("naming_service") + bool Ready; /// true if the service is ready + vector Commands; + +private: + static uint32 NextId; +}; + +uint32 CService::NextId = 1; + +list Services; +typedef list::iterator SIT; + +SIT find (TSockId sid) +{ + SIT sit; + for (sit = Services.begin(); sit != Services.end(); sit++) + { + if ((*sit).SockId == sid) break; + } + return sit; +} + +SIT findService (uint32 sid, bool asrt = true) +{ + SIT sit; + for (sit = Services.begin(); sit != Services.end(); sit++) + { + if ((*sit).Id == sid) break; + } + if (asrt) + nlassert (sit != Services.end()); + return sit; +} + + +class CExecuteCommandThread : public IRunnable +{ +public: + string Command, Path; + + CExecuteCommandThread (string command, string path = "") : Command(command), Path(path) { } + + void run () + { + nlinfo ("start executing '%s' in '%s' directory", Command.c_str(), Path.c_str()); + + char oldpath[256]; + if (!Path.empty()) + { + getcwd(oldpath,256); + chdir(Path.c_str()); + } + + system (Command.c_str()); + + if (!Path.empty()) + chdir(oldpath); + + nlinfo ("end executing: %s", Command.c_str()); + } +}; + +class CExecuteServiceThread : public IRunnable +{ +public: + string ServiceAlias, ServiceCommand, ServicePath; + + CExecuteServiceThread (string serviceAlias, string serviceCommand, string servicePath = "") : + ServiceCommand(serviceCommand), ServicePath(servicePath), ServiceAlias(serviceAlias) { } + + void run () + { + nlinfo ("start service '%s' '%s' in '%s' directory", ServiceAlias.c_str(), ServiceCommand.c_str(), ServicePath.c_str()); + + char oldpath[256]; + if (!ServicePath.empty()) + { + getcwd(oldpath,256); + chdir(ServicePath.c_str()); + } + + system (ServiceCommand.c_str()); + + if (!ServicePath.empty()) + chdir(oldpath); + + nlinfo ("end service '%s' '%s' in '%s' directory", ServiceAlias.c_str(), ServiceCommand.c_str(), ServicePath.c_str()); + } +}; + +void executeCommand (string command, bool background) +{ + if (command.empty()) return; + +/* + nlinfo ("start executing: %s", command.c_str()); + if (command[command.size()-1] == '&') + { + command.resize(command.size()-2); + + if (spawnlp (_P_NOWAIT, cmd.c_str(), command.c_str(), NULL) == -1) + { + perror ("ca chie grave!!!!: "); + } + } + else + { + if (spawnlp (_P_WAIT, cmd.c_str(), command.c_str(), NULL) == -1) + { + perror ("ca chie grave!!!!: "); + } + } + nlinfo ("end executing: %s", command.c_str()); +*/ + + command += " >NUL:"; + if (background) + { + IThread *thread = IThread::create (new CExecuteCommandThread (command)); + thread->start (); + } + else + { + CExecuteCommandThread cmdt (command); + cmdt.run (); + } +} + + +/* +// execute without +void executeCommand (string command, TSockId from, CCallbackNetBase &netbase) +{ + if (command.empty()) return; + + #define STDOUT 1 + #define STDERR 2 + int nul, oldstdout, oldstderr; + char *tmpfilename = tmpnam (NULL); + nul = _open(tmpfilename, _O_RDWR | _O_CREAT | _O_TRUNC | _O_TEMPORARY | _O_SHORT_LIVED | _O_EXCL, _S_IREAD | _S_IWRITE); + oldstdout = _dup(STDOUT); + oldstderr = _dup(STDERR); + _dup2(nul, STDOUT); + _dup2(nul, STDERR); + system(command.c_str()); + _dup2(oldstdout, STDOUT); + _dup2(oldstderr, STDERR); + _close(oldstdout); + _close(oldstderr); + + _lseek (nul, 0L, SEEK_SET); + + while (!_eof(nul)) + { + uint8 buffer[10000]; + uint32 nbread = _read (nul, buffer, 10000); + + CMessage msgout (netbase.getSIDA(), "ESCR"); + msgout.serial (nbread); + msgout.serialBuffer (buffer, nbread); + netbase.send (msgout, from); + } + + _close(nul); +*/ +/* + FILE *fp = fopen ("test.txt", "r"); + do + { + char str[1024]; + fgets (str, 1024, fp); + if (feof(fp)) break; + result.push_back (str); + } + while (true); + fclose (fp); +// remove ("test.txt"); +*///} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////// CONNECTION TO THE SERVICES ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +static void cbServiceIdentification (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + CService *s = (CService*) (uint) from->appId(); + + msgin.serial (s->AliasName, s->ShortName, s->LongName); + msgin.serialCont (s->Commands); + + nlinfo ("*:*:%d is identified to be '%s' '%s' '%s'", s->Id, s->AliasName.c_str(), s->ShortName.c_str(), s->LongName.c_str()); + + // broadcast the message to the admin service + CMessage msgout (CNetManager::getSIDA ("AESAS"), "SID"); + msgout.serial (s->Id, s->AliasName, s->ShortName, s->LongName); + msgout.serialCont (s->Commands); + CNetManager::send ("AESAS", msgout); +} + +static void cbServiceReady (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + CService *s = (CService*) (uint) from->appId(); + + nlinfo ("*:*:%d is ready", s->Id); + s->Ready = true; + + // broadcast the message to the admin service + CMessage msgout (CNetManager::getSIDA ("AESAS"), "SR"); + msgout.serial (s->Id); + CNetManager::send ("AESAS", msgout); +} + +static void cbLog (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + CService *s = (CService*) (uint) from->appId(); + // received an answer for a command, give it to the AS + + // broadcast the message to the admin service + CMessage msgout (CNetManager::getSIDA ("AESAS"), "XLOG"); + string log; + msgin.serial (log); + msgout.serial (s->Id); + msgout.serial (log); + CNetManager::send ("AESAS", msgout); +} + +void serviceConnection (const string &serviceName, TSockId from, void *arg) +{ + Services.push_back (CService (from)); + CService *s = &(Services.back()); + from->setAppId ((uint64)(uint)s); + + nlinfo ("*:*:%d connected", s->Id); + + // broadcast the message to the admin service + CMessage msgout (CNetManager::getSIDA ("AESAS"), "SC"); + msgout.serial (s->Id); + CNetManager::send ("AESAS", msgout); +} + +void serviceDisconnection (const string &serviceName, TSockId from, void *arg) +{ + CService *s = (CService*) (uint) from->appId(); + + nlinfo ("*:*:%d disconnected", s->Id); + + // broadcast the message to the admin service + CMessage msgout (CNetManager::getSIDA ("AESAS"), "SD"); + msgout.serial (s->Id); + CNetManager::send ("AESAS", msgout); + + // remove the service from the list + Services.erase (findService(s->Id)); +} + + +/** Callback Array + */ +TCallbackItem ServicesCallbackArray[] = +{ + { "SID", cbServiceIdentification }, + { "SR", cbServiceReady }, + { "LOG", cbLog }, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////// CONNECTION TO THE AS //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +void errorMessage(string message, TSockId from) +{ + CMessage msgout (CNetManager::getSIDA ("AESAS"), "ERR"); + msgout.serial (message); + CNetManager::send ("AESAS", msgout, from); +} + +static void cbExecuteSystemCommand (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + string command; + + msgin.serial (command); + + IThread *thread = IThread::create (new CExecuteCommandThread (command)); + thread->start (); +} + +static void cbStartService (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + string serviceAlias, command, path; + msgin.serial (serviceAlias); + + nlinfo ("Starting the service alias '%s'", serviceAlias.c_str()); + + try + { + path = IService::ConfigFile.getVar(serviceAlias).asString(0); + command = IService::ConfigFile.getVar(serviceAlias).asString(1); + } + catch(EConfigFile &e) + { + nlwarning ("error in serviceAlias '%s' in config file (%s)", serviceAlias.c_str(), e.what()); + return; + } + + // give the service alias to the service to forward it back when it will connected to the aes. + command += " -n"; + command += serviceAlias.c_str(); + + command += " >NUL:"; + + IThread *thread = IThread::create (new CExecuteServiceThread (serviceAlias, command, path)); + thread->start (); +} + +static void cbStopService (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + uint32 sid; + + msgin.serial (sid); + + nlinfo ("I have to stop service '%s'"); + + SIT sit = findService (sid, false); + if (sit == Services.end()) + { + // don't find the aes, send an error message + errorMessage ("couldn't stop service, aes didn't find the service", from); + return; + } + + CMessage msgout (CNetManager::getSIDA("AES"), "STOPS"); + CNetManager::send ("AES", msgout, (*sit).SockId); +} + +static void cbExecCommand (CMessage& msgin, TSockId from, CCallbackNetBase &netbase) +{ + uint32 sid; + string command; + + msgin.serial (sid); + msgin.serial (command); + + SIT sit = findService (sid, false); + if (sit == Services.end()) + { + // don't find the aes, send an error message + errorMessage ("couldn't stop service, aes didn't find the service", from); + return; + } + + CMessage msgout (CNetManager::getSIDA("AES"), "EXEC_COMMAND"); + msgout.serial (command); + CNetManager::send ("AES", msgout, (*sit).SockId); +} + +void loadAndSendServicesAliasList (CConfigFile::CVar &var); + +void cbASServiceConnection (const string &serviceName, TSockId from, void *arg) +{ + // new admin service, send him all out info about services + + nlinfo ("AS %s is connected", from->asString().c_str()); + + CMessage msgout (CNetManager::getSIDA ("AESAS"), "SL"); + uint32 nbs = (uint32)Services.size(); + msgout.serial (nbs); + for (SIT sit = Services.begin(); sit != Services.end(); sit++) + { + msgout.serial ((*sit).Id, (*sit).AliasName, (*sit).ShortName, (*sit).LongName, (*sit).Ready); + msgout.serialCont ((*sit).Commands); + } + CNetManager::send ("AESAS", msgout, from); + + loadAndSendServicesAliasList (IService::ConfigFile.getVar ("Services")); +} + +TCallbackItem AESASCallbackArray[] = +{ + { "SYS", cbExecuteSystemCommand }, + { "STARTS", cbStartService }, + { "STOPS", cbStopService }, + { "EXEC_COMMAND", cbExecCommand }, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////// SERVICE IMPLEMENTATION ////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +void loadAndSendServicesAliasList (CConfigFile::CVar &services) +{ + vector servicesaliaslist; + for (sint i = 0 ; i < services.size (); i++) + { + servicesaliaslist.push_back (services.asString(i)); + } + + CMessage msgout2 (CNetManager::getSIDA ("AESAS"), "SAL"); + msgout2.serialCont (servicesaliaslist); + CNetManager::send ("AESAS", msgout2, 0); +} + + +class CAdminExecutorService : public IService +{ +public: + + /// Init the service, load the universal time. + void init () + { + CNetManager::setConnectionCallback ("AES", serviceConnection, NULL); + CNetManager::setDisconnectionCallback ("AES", serviceDisconnection, NULL); + + // install the server for AS + CNetManager::setConnectionCallback ("AESAS", cbASServiceConnection, NULL); + CNetManager::addServer ("AESAS", 49996); + CNetManager::addCallbackArray ("AESAS", AESASCallbackArray, sizeof(AESASCallbackArray)/sizeof(AESASCallbackArray[0])); + + ConfigFile.setCallback ("Services", loadAndSendServicesAliasList); + loadAndSendServicesAliasList (IService::ConfigFile.getVar ("Services")); + } + + bool update () + { + return true; + } +}; + + +/// Naming Service +NLNET_SERVICE_MAIN (CAdminExecutorService, "AES", "admin_executor_service", 49997, ServicesCallbackArray); -- cgit v1.2.1