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 | 43 ++ .../plain/index.html | 14 + .../plain&sortby=date/index.html | 15 + .../plain/index.html | 17 + .../admin_executor_service/Makefile.am?rev=1.6 | 15 + .../plain&sortby=date/index.html | 15 + .../plain&sortby=date/index.html | 16 + .../plain/index.html | 10 + .../plain/index.html | 8 + .../plain/index.html | 10 + .../admin_executor_service.cfg?rev=1.7 | 8 + .../plain&rev=1.12 | 518 ++++++++++++++++++++ .../plain/index.html | 181 +++++++ .../plain/index.html | 505 ++++++++++++++++++++ .../plain/index.html | 530 +++++++++++++++++++++ .../plain/index.html | 518 ++++++++++++++++++++ 16 files changed, 2423 insertions(+) create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Attic/sysload.h?rev=1.1&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.3&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.4&content-type=text/plain&sortby=date/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.5&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6 create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6&content-type=text/plain&sortby=date/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.7&content-type=text/plain&sortby=date/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.2&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.5&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.6&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.7 create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?content-type=text/plain&rev=1.12 create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.1&content-type=text/plain/index.html 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 create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.13&content-type=text/plain/index.html create mode 100644 cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.14&content-type=text/plain/index.html (limited to 'cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service') diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Attic/sysload.h?rev=1.1&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Attic/sysload.h?rev=1.1&content-type=text/plain/index.html new file mode 100644 index 00000000..4291e873 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Attic/sysload.h?rev=1.1&content-type=text/plain/index.html @@ -0,0 +1,43 @@ +/** \file sysload.h + * + * $Id: sysload.h,v 1.1 2001/04/18 13:54:25 valignat 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. + */ + + +#ifndef NL_SYSLOAD_H +#define NL_SYSLOAD_H + + +class CSysLoad +{ +public: + CSysLoad ( void ); + ~CSysLoad ( void ); + + /// Returns the system load + double getLoadInfo ( void ); +}; + + +#endif // NL_SYSLOAD_H + +// End of sysload.h diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.3&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.3&content-type=text/plain/index.html new file mode 100644 index 00000000..3582ac47 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.3&content-type=text/plain/index.html @@ -0,0 +1,14 @@ +# +# $Id: Makefile.am,v 1.3 2001/05/03 13:19:13 lecroart Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +bin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +admin_executor_service_LDADD = -lnelnet -lnelmisc + + +# End of Makefile.am diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.4&content-type=text/plain&sortby=date/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.4&content-type=text/plain&sortby=date/index.html new file mode 100644 index 00000000..8fb69ecf --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.4&content-type=text/plain&sortby=date/index.html @@ -0,0 +1,15 @@ +# +# $Id: Makefile.am,v 1.4 2001/07/27 15:51:10 valignat Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +bin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +admin_executor_service_LDADD = -lnelnet -lnelmisc + + +# End of Makefile.am + diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.5&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.5&content-type=text/plain/index.html new file mode 100644 index 00000000..2edf32ad --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.5&content-type=text/plain/index.html @@ -0,0 +1,17 @@ +# +# $Id: Makefile.am,v 1.5 2002/03/19 17:42:48 valignat Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = admin_executor_service.cfg \ + admin_executor_service.dsp + +sbin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +pkgsysconf_DATA = admin_executor_service.cfg + +# End of Makefile.am + diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6 b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6 new file mode 100644 index 00000000..bc71c7a8 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6 @@ -0,0 +1,15 @@ +# +# $Id: Makefile.am,v 1.6 2002/04/10 07:33:07 lecroart Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = admin_executor_service.cfg \ + admin_executor_service.dsp + +sbin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +# End of Makefile.am + diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6&content-type=text/plain&sortby=date/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6&content-type=text/plain&sortby=date/index.html new file mode 100644 index 00000000..bc71c7a8 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6&content-type=text/plain&sortby=date/index.html @@ -0,0 +1,15 @@ +# +# $Id: Makefile.am,v 1.6 2002/04/10 07:33:07 lecroart Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = admin_executor_service.cfg \ + admin_executor_service.dsp + +sbin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +# End of Makefile.am + diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.7&content-type=text/plain&sortby=date/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.7&content-type=text/plain&sortby=date/index.html new file mode 100644 index 00000000..06b4d371 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.7&content-type=text/plain&sortby=date/index.html @@ -0,0 +1,16 @@ +# +# $Id: Makefile.am,v 1.7 2002/06/12 10:21:25 lecroart Exp $ +# + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = admin_executor_service.cfg \ + admin_executor_service.dsp \ + common.cfg + +sbin_PROGRAMS = admin_executor_service + +admin_executor_service_SOURCES = admin_executor_service.cpp + +# End of Makefile.am + diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.2&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.2&content-type=text/plain/index.html new file mode 100644 index 00000000..d751b593 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.2&content-type=text/plain/index.html @@ -0,0 +1,10 @@ + +Services = { "TS", "NS" }; + +NS = { "r:\code\nelns\naming_service", "r:\code\nelns\naming_service\debug\naming_service.exe" }; +TS = { "r:\code\nelns\time_service", "r:\code\nelns\time_service\debug\time_service.exe" }; + +XWinParam = 0; +YWinParam = 250; +WWinParam = 1200; +HWinParam = 300; diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.5&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.5&content-type=text/plain/index.html new file mode 100644 index 00000000..9cae3d77 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.5&content-type=text/plain/index.html @@ -0,0 +1,8 @@ + +Services = { "NS", "LS", "WS" }; + +NS = { "r:\code\nelns\naming_service", "r:\code\nelns\naming_service\debug\naming_service.exe" }; +LS = { "r:\code\nelns\login_service", "r:\code\nelns\login_service\debug\login_service.exe" }; +WS = { "r:\code\nelns\welcome_service", "r:\code\nelns\welcome_service\debug\welcome_service.exe" }; + +WindowStyle = "WIN"; diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.6&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.6&content-type=text/plain/index.html new file mode 100644 index 00000000..198b84c7 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.6&content-type=text/plain/index.html @@ -0,0 +1,10 @@ +// link the common configuration file +RootConfigFilename = "common.cfg"; + +Services = { "NS", "LS", "WS" }; + +NS = { "r:\code\nelns\naming_service", "r:\code\nelns\naming_service\debug\naming_service.exe" }; +LS = { "r:\code\nelns\login_service", "r:\code\nelns\login_service\debug\login_service.exe" }; +WS = { "r:\code\nelns\welcome_service", "r:\code\nelns\welcome_service\debug\welcome_service.exe" }; + +WindowStyle = "WIN"; diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.7 b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.7 new file mode 100644 index 00000000..eecb0621 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.7 @@ -0,0 +1,8 @@ +// link the common configuration file +RootConfigFilename = "common.cfg"; + +Services = { "NS", "LS", "WS" }; + +NS = { "r:\code\nelns\naming_service", "r:\code\nelns\naming_service\debug\naming_service.exe" }; +LS = { "r:\code\nelns\login_service", "r:\code\nelns\login_service\debug\login_service.exe" }; +WS = { "r:\code\nelns\welcome_service", "r:\code\nelns\welcome_service\debug\welcome_service.exe" }; diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?content-type=text/plain&rev=1.12 b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?content-type=text/plain&rev=1.12 new file mode 100644 index 00000000..3e29a0ba --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?content-type=text/plain&rev=1.12 @@ -0,0 +1,518 @@ +/** \file admin_executor_service.cpp + * Admin Executor Service (AES) + * + * $Id: admin_executor_service.cpp,v 1.12 2001/10/22 10:35:49 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 +#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()); + } + +#ifdef NL_OS_WINDOWS + WinExec (ServiceCommand.c_str(), SW_MINIMIZE/*SW_SHOWNORMAL*/); +#else + system (ServiceCommand.c_str()); +#endif + + 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()); +*/ + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + 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(); + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + + 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); diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.1&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.1&content-type=text/plain/index.html new file mode 100644 index 00000000..8a183cb4 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.1&content-type=text/plain/index.html @@ -0,0 +1,181 @@ +/** \file admin_executor_service.cpp + * Admin Executor Service (AES) + * + * $Id: admin_executor_service.cpp,v 1.1 2001/04/18 13:54:25 valignat 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 +#include +#include + +#include "sysload.h" +#include "sysmem.h" +#include "sysswap.h" + +using namespace std; +using namespace NLMISC; +using namespace NLNET; + + +static const char UNKNOW_VALUE[] = ""; + + +CLog StatLog(CLog::LOG_STAT); + + +/// Log Stat data (STT) +void sendData (const char *str, TSenderId from) +{ + StatLog.displayNL( str ); +} + + +/// Log the last minute average load +void cbLoad ( CMessage& message, TSenderId from ) +{ + CSysLoad sysload = CSysLoad(); + double load = sysload.getLoadInfo(); + string answer( "LOAD " ); + + if ( load < 0 ) + { + answer.append( UNKNOW_VALUE ); + } + else + { + char str[6]; + smprintf( str, 6, "%.2f", load ); + answer.append( string(str) ); + } + + sendData( answer.c_str(), from ); +} + + +/// Log the total memory size and the used memory size (in B) +void cbMemory ( CMessage& message, TSenderId from ) +{ + CSysMemory sysmem = CSysMemory(); + sint memUsage = sysmem.getMemoryUsage(); + string answer( "MEM " ); + + if ( memUsage < 0 ) + { + answer.append( UNKNOW_VALUE ); + } + else + { + char str[3]; + smprintf( str, 3, "%d", memUsage ); + answer.append( string(str) ); + } + + sendData( answer.c_str(), from ); +} + + +/// Log the swap size and the used swap space (in kB) +void cbSwap ( CMessage& message, TSenderId from ) +{ + CSysSwap sysswap = CSysSwap(); + sint swapUsage = sysswap.getSwapUsage(); + string answer( "SWAP " ); + + if ( swapUsage < 0 ) + { + answer.append( UNKNOW_VALUE ); + } + else + { + char str[3]; + smprintf( str, 3, "%d", swapUsage ); + answer.append( string(str) ); + } + + sendData( answer.c_str(), from ); +} + + +// Log all the server informations. +void cbSystem ( CMessage& message, TSenderId from ) +{ + cbLoad ( message, from ); + cbMemory ( message, from ); + cbSwap ( message, from ); +} + + +/** + * Callback Array + * Message types: + * LOAD: log Load information + * MEMORY: log Memory information + * SWAP: log Swap information + * SYSTEM: log the Load, Memory, and Swap informations + */ +TCallbackItem CallbackArray[] = +{ + { "LOAD", cbLoad }, + { "MEMORY", cbMemory }, + { "SWAP", cbSwap }, + + { "SYSTEM", cbSystem } +}; + + + +/** Admin Executor Service (AES). + * Log informations (load, memory usage, etc ...) about the server it's + * running on. + * These informations are used by the Admin Service (AS) and the Naming + * Service (NS) to watch the differents servers of the shard. + */ +class CAdminExecutorService : public NLNET::IService +{ +public: + + /// Initializes the service + void init () + { + // Connect to the Log Service + StatLog.addDisplayer( new NLMISC::CStdDisplayer() ); + + NLNET::CNetDisplayer *nd = new NLNET::CNetDisplayer; + + if ( nd->connected() ) + { + StatLog.addDisplayer( nd ); + } + else + { + nlerror( "Coudn't connect to the Log Service." ); + } + } + +}; + + +NLNET_SERVICE_MAIN( CAdminExecutorService, "AES", 50009 ); + +// End of admin_executor_service.cpp 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); diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.13&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.13&content-type=text/plain/index.html new file mode 100644 index 00000000..6d314728 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.13&content-type=text/plain/index.html @@ -0,0 +1,530 @@ +/** \file admin_executor_service.cpp + * Admin Executor Service (AES) + * + * $Id: admin_executor_service.cpp,v 1.13 2002/03/19 17:42:48 valignat 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifndef NELNS_CONFIG +#define NELNS_CONFIG "" +#endif // NELNS_CONFIG + +#ifndef NELNS_LOGS +#define NELNS_LOGS "" +#endif // NELNS_LOGS + +#include +#include + +#include "nel/misc/types_nl.h" + +#ifdef NL_OS_WINDOWS +#include +#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()); + } + +#ifdef NL_OS_WINDOWS + WinExec (ServiceCommand.c_str(), SW_MINIMIZE/*SW_SHOWNORMAL*/); +#else + system (ServiceCommand.c_str()); +#endif + + 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()); +*/ + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + 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(); + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + + 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, NELNS_CONFIG, NELNS_LOGS); diff --git a/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.14&content-type=text/plain/index.html b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.14&content-type=text/plain/index.html new file mode 100644 index 00000000..12ee8936 --- /dev/null +++ b/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.14&content-type=text/plain/index.html @@ -0,0 +1,518 @@ +/** \file admin_executor_service.cpp + * Admin Executor Service (AES) + * + * $Id: admin_executor_service.cpp,v 1.14 2002/03/25 09:27:34 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifndef NELNS_CONFIG +#define NELNS_CONFIG "" +#endif // NELNS_CONFIG + +#ifndef NELNS_LOGS +#define NELNS_LOGS "" +#endif // NELNS_LOGS + +#include "nel/misc/types_nl.h" + +#include +#include + +#ifdef NL_OS_WINDOWS +#include +#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; + + CExecuteCommandThread (string command) : Command(command) { } + + void run () + { + nlinfo ("start executing '%s'", Command.c_str()); + + system (Command.c_str()); + + nlinfo ("end executing: %s", Command.c_str()); + } +}; + +class CExecuteServiceThread : public IRunnable +{ +public: + string ServiceCommand; + + CExecuteServiceThread (string serviceCommand) : + ServiceCommand(serviceCommand) { } + + void run () + { + nlinfo ("start service '%s'", ServiceCommand.c_str()); + +#ifdef NL_OS_WINDOWS + WinExec (ServiceCommand.c_str(), SW_MINIMIZE/*SW_SHOWNORMAL*/); +#else + system (ServiceCommand.c_str()); +#endif + + nlinfo ("end service '%s'", ServiceCommand.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()); +*/ + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + 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::getInstance()->ConfigFile.getVar(serviceAlias).asString(0); + command = IService::getInstance()->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; + + // set the path for the config file + command += " -C"; + command += path; + + // set the path for log + command += " -L"; + command += path; + +#ifdef NL_OS_WINDOWS + command += " >NUL:"; +#else + command += " >/dev/null"; +#endif + + IThread *thread = IThread::create (new CExecuteServiceThread (command)); + 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::getInstance()->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_OLD_SERVICE_MAIN (CAdminExecutorService, "AES", "admin_executor_service", 49997, ServicesCallbackArray, NELNS_CONFIG, NELNS_LOGS); -- cgit v1.2.1