aboutsummaryrefslogtreecommitdiff
path: root/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service
diff options
context:
space:
mode:
Diffstat (limited to 'cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service')
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Attic/sysload.h?rev=1.1&content-type=text/plain/index.html43
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.3&content-type=text/plain/index.html14
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.4&content-type=text/plain&sortby=date/index.html15
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.5&content-type=text/plain/index.html17
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.615
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.6&content-type=text/plain&sortby=date/index.html15
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/Makefile.am?rev=1.7&content-type=text/plain&sortby=date/index.html16
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.2&content-type=text/plain/index.html10
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.5&content-type=text/plain/index.html8
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.6&content-type=text/plain/index.html10
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cfg?rev=1.78
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?content-type=text/plain&rev=1.12518
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.1&content-type=text/plain/index.html181
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.10&content-type=text/plain/index.html505
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.13&content-type=text/plain/index.html530
-rw-r--r--cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.14&content-type=text/plain/index.html518
16 files changed, 2423 insertions, 0 deletions
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 <fcntl.h>
+#include <sys/stat.h>
+
+#include "nel/misc/types_nl.h"
+
+#ifdef NL_OS_WINDOWS
+#include <windows.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <string>
+#include <list>
+
+#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<CSerialCommand> Commands;
+
+private:
+ static uint32 NextId;
+};
+
+uint32 CService::NextId = 1;
+
+list<CService> Services;
+typedef list<CService>::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<string> 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 <nel/misc/debug.h>
+#include <nel/misc/log.h>
+#include <nel/misc/common.h>
+#include <nel/net/service.h>
+#include <nel/net/net_displayer.h>
+
+#include "sysload.h"
+#include "sysmem.h"
+#include "sysswap.h"
+
+using namespace std;
+using namespace NLMISC;
+using namespace NLNET;
+
+
+static const char UNKNOW_VALUE[] = "<Unknown>";
+
+
+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 <fcntl.h>
+#include <sys/stat.h>
+
+#include "nel/misc/types_nl.h"
+
+#ifdef NL_OS_WINDOWS
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <string>
+#include <list>
+
+#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<CSerialCommand> Commands;
+
+private:
+ static uint32 NextId;
+};
+
+uint32 CService::NextId = 1;
+
+list<CService> Services;
+typedef list<CService>::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<string> 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 <fcntl.h>
+#include <sys/stat.h>
+
+#include "nel/misc/types_nl.h"
+
+#ifdef NL_OS_WINDOWS
+#include <windows.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <string>
+#include <list>
+
+#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<CSerialCommand> Commands;
+
+private:
+ static uint32 NextId;
+};
+
+uint32 CService::NextId = 1;
+
+list<CService> Services;
+typedef list<CService>::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<string> 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 <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef NL_OS_WINDOWS
+#include <windows.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <string>
+#include <list>
+
+#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<CSerialCommand> Commands;
+
+private:
+ static uint32 NextId;
+};
+
+uint32 CService::NextId = 1;
+
+list<CService> Services;
+typedef list<CService>::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<string> 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);