aboutsummaryrefslogtreecommitdiff
path: root/cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html')
-rw-r--r--cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html516
1 files changed, 516 insertions, 0 deletions
diff --git a/cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html b/cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html
new file mode 100644
index 00000000..ee691d76
--- /dev/null
+++ b/cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9&content-type=text/x-cvsweb-markup/index.html
@@ -0,0 +1,516 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
+<HEAD><style> A { color:black }</style>
+<!-- hennerik CVSweb $Revision: 1.93 $ -->
+<TITLE>code/nelns/admin_executor_service/admin_executor_service.cpp - view - 1.9</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee">
+<table width="100%" border=0 cellspacing=0 cellpadding=1 bgcolor="#aaaaaa"><tr valign=bottom><td><a href="admin_executor_service.cpp"><IMG SRC="http://www.nevrax.org/inc/img/picto-up.gif" ALT="[BACK]" BORDER="0" WIDTH="14" HEIGHT="13"></a> <b>Return to <A HREF="admin_executor_service.cpp">admin_executor_service.cpp</A>
+ CVS log</b> <IMG SRC="http://www.nevrax.org/inc/img/picto-news.gif" ALT="[TXT]" BORDER="0" WIDTH="13" HEIGHT="15"></td><td align=right><IMG SRC="http://www.nevrax.org/inc/img/picto-dir.gif" ALT="[DIR]" BORDER="0" WIDTH="15" HEIGHT="13"> <b>Up to <a href="/cvs/cvsweb.cgi/">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/">code</a> / <a href="/cvs/cvsweb.cgi/code/nelns/">nelns</a> / <a href="/cvs/cvsweb.cgi/code/nelns/admin_executor_service/">admin_executor_service</a></b></td></tr></table><HR noshade><table width="100%"><tr><td bgcolor="#ffffff">File: <a href="/cvs/cvsweb.cgi/">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/">code</a> / <a href="/cvs/cvsweb.cgi/code/nelns/">nelns</a> / <a href="/cvs/cvsweb.cgi/code/nelns/admin_executor_service/">admin_executor_service</a> / <a href="/cvs/cvsweb.cgi/code/nelns/admin_executor_service/admin_executor_service.cpp">admin_executor_service.cpp</a>&nbsp;(<A HREF="/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9" target="cvs_checkout" onClick="window.open('/cvs/cvsweb.cgi/~checkout~/code/nelns/admin_executor_service/admin_executor_service.cpp?rev=1.9','cvs_checkout','resizeable,scrollbars');"><b>download</b></A>)<BR>
+Revision <B>1.9</B>, <i>Mon Jun 18 14:54:06 2001 UTC</i> (13 months ago) by <i>lecroart</i>
+<BR>Branch: <b>MAIN</b>
+<BR>Changes since <b>1.8: +5 -5
+ lines</b><PRE>
+BUGFIX: linux compilation
+</PRE>
+</td></tr></table><HR noshade><PRE>/** \file admin_executor_service.cpp
+ * Admin Executor Service (AES)
+ *
+ * $Id: admin_executor_service.cpp,v 1.9 2001/06/18 14:54:06 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 &lt;fcntl.h&gt;
+#include &lt;sys/stat.h&gt;
+
+#include &quot;nel/misc/types_nl.h&quot;
+
+#ifdef NL_OS_WINDOWS
+#include &lt;direct.h&gt;
+#else
+#include &lt;unistd.h&gt;
+#endif
+
+#include &lt;string&gt;
+#include &lt;list&gt;
+
+#include &quot;nel/misc/debug.h&quot;
+#include &quot;nel/misc/config_file.h&quot;
+#include &quot;nel/misc/thread.h&quot;
+
+#include &quot;nel/net/service.h&quot;
+#include &quot;nel/net/net_manager.h&quot;
+
+#ifdef NL_OS_WINDOWS
+#define getcwd _getcwd
+#define chdir _chdir
+#endif
+
+
+using namespace std;
+using namespace NLMISC;
+using namespace NLNET;
+
+
+
+struct CService
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CService(TSockId s) : SockId(s), Id(NextId++), Ready(false) { }
+
+ &nbsp; &nbsp; &nbsp; &nbsp;TSockId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SockId; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// connection to the service
+ &nbsp; &nbsp; &nbsp; &nbsp;uint32 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Id; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// uint32 to identify the service
+ &nbsp; &nbsp; &nbsp; &nbsp;string &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AliasName; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// alias of the service used in the AES and AS to find him (unique per AES)
+ &nbsp; &nbsp; &nbsp; &nbsp;string &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShortName; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// name of the service in short format (&quot;NS&quot; for example)
+ &nbsp; &nbsp; &nbsp; &nbsp;string &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LongName; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// name of the service in long format (&quot;naming_service&quot;)
+ &nbsp; &nbsp; &nbsp; &nbsp;bool &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ready; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/// true if the service is ready
+ &nbsp; &nbsp; &nbsp; &nbsp;vector&lt;string&gt; &nbsp; &nbsp; &nbsp; &nbsp;Commands;
+
+private:
+ &nbsp; &nbsp; &nbsp; &nbsp;static &nbsp; &nbsp; &nbsp; &nbsp;uint32 NextId;
+};
+
+uint32 CService::NextId = 1;
+
+list&lt;CService&gt; Services;
+typedef list&lt;CService&gt;::iterator SIT;
+
+SIT find (TSockId sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;SIT sit;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (sit = Services.begin(); sit != Services.end(); sit++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*sit).SockId == sid) break;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;return sit;
+}
+
+SIT findService (uint32 sid, bool asrt = true)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;SIT sit;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (sit = Services.begin(); sit != Services.end(); sit++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*sit).Id == sid) break;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;if (asrt)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlassert (sit != Services.end());
+ &nbsp; &nbsp; &nbsp; &nbsp;return sit;
+}
+
+
+class CExecuteCommandThread : public IRunnable
+{
+public:
+ &nbsp; &nbsp; &nbsp; &nbsp;string Command, Path;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CExecuteCommandThread (string command, string path = &quot;&quot;) : Command(command), Path(path) { }
+
+ &nbsp; &nbsp; &nbsp; &nbsp;void run ()
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;start executing '%s' in '%s' directory&quot;, Command.c_str(), Path.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char oldpath[256];
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!Path.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getcwd(oldpath,256);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;chdir(Path.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;system (Command.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!Path.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;chdir(oldpath);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;end executing: %s&quot;, Command.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+};
+
+class CExecuteServiceThread : public IRunnable
+{
+public:
+ &nbsp; &nbsp; &nbsp; &nbsp;string ServiceAlias, ServiceCommand, ServicePath;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CExecuteServiceThread (string serviceAlias, string serviceCommand, string servicePath = &quot;&quot;) :
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ServiceCommand(serviceCommand), ServicePath(servicePath), ServiceAlias(serviceAlias) { }
+
+ &nbsp; &nbsp; &nbsp; &nbsp;void run ()
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;start service '%s' '%s' in '%s' directory&quot;, ServiceAlias.c_str(), ServiceCommand.c_str(), ServicePath.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char oldpath[256];
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!ServicePath.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getcwd(oldpath,256);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;chdir(ServicePath.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;system (ServiceCommand.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!ServicePath.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;chdir(oldpath);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;end service '%s' '%s' in '%s' directory&quot;, ServiceAlias.c_str(), ServiceCommand.c_str(), ServicePath.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+};
+
+void executeCommand (string command, bool background)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if (command.empty()) return;
+
+/*
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;start executing: %s&quot;, command.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;if (command[command.size()-1] == '&amp;')
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;command.resize(command.size()-2);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (spawnlp (_P_NOWAIT, cmd.c_str(), command.c_str(), NULL) == -1)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;perror (&quot;ca chie grave!!!!: &quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (spawnlp (_P_WAIT, cmd.c_str(), command.c_str(), NULL) == -1)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;perror (&quot;ca chie grave!!!!: &quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;end executing: %s&quot;, command.c_str());
+*/
+
+ &nbsp; &nbsp; &nbsp; &nbsp;command += &quot; &gt;NUL:&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp;if (background)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IThread *thread = IThread::create (new CExecuteCommandThread (command));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;thread-&gt;start ();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CExecuteCommandThread cmdt (command);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmdt.run ();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+
+/*
+// execute without
+void executeCommand (string command, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if (command.empty()) return;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;#define STDOUT 1
+ &nbsp; &nbsp; &nbsp; &nbsp;#define STDERR 2
+ &nbsp; &nbsp; &nbsp; &nbsp;int nul, oldstdout, oldstderr;
+ &nbsp; &nbsp; &nbsp; &nbsp;char *tmpfilename = tmpnam (NULL);
+ &nbsp; &nbsp; &nbsp; &nbsp;nul = _open(tmpfilename, _O_RDWR | _O_CREAT | _O_TRUNC | _O_TEMPORARY | _O_SHORT_LIVED | _O_EXCL, _S_IREAD | _S_IWRITE);
+ &nbsp; &nbsp; &nbsp; &nbsp;oldstdout = _dup(STDOUT);
+ &nbsp; &nbsp; &nbsp; &nbsp;oldstderr = _dup(STDERR);
+ &nbsp; &nbsp; &nbsp; &nbsp;_dup2(nul, STDOUT);
+ &nbsp; &nbsp; &nbsp; &nbsp;_dup2(nul, STDERR);
+ &nbsp; &nbsp; &nbsp; &nbsp;system(command.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;_dup2(oldstdout, STDOUT);
+ &nbsp; &nbsp; &nbsp; &nbsp;_dup2(oldstderr, STDERR);
+ &nbsp; &nbsp; &nbsp; &nbsp;_close(oldstdout);
+ &nbsp; &nbsp; &nbsp; &nbsp;_close(oldstderr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;_lseek (nul, 0L, SEEK_SET);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!_eof(nul))
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint8 buffer[10000];
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint32 nbread = _read (nul, buffer, 10000);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (netbase.getSIDA(), &quot;ESCR&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (nbread);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serialBuffer (buffer, nbread);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;netbase.send (msgout, from);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;_close(nul);
+*/
+/*
+ &nbsp; &nbsp; &nbsp; &nbsp;FILE *fp = fopen (&quot;test.txt&quot;, &quot;r&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;do
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char str[1024];
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fgets (str, 1024, fp);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (feof(fp)) break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result.push_back (str);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;while (true);
+ &nbsp; &nbsp; &nbsp; &nbsp;fclose (fp);
+// &nbsp; &nbsp; &nbsp;remove (&quot;test.txt&quot;);
+*///}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////// CONNECTION TO THE SERVICES //////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void cbServiceIdentification (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CService *s = (CService*) (uint) from-&gt;appId();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (s-&gt;AliasName, s-&gt;ShortName, s-&gt;LongName);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serialCont (s-&gt;Commands);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;*:*:%d is identified to be '%s' '%s' '%s'&quot;, s-&gt;Id, s-&gt;AliasName.c_str(), s-&gt;ShortName.c_str(), s-&gt;LongName.c_str());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// broadcast the message to the admin service
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SID&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (s-&gt;Id, s-&gt;AliasName, s-&gt;ShortName, s-&gt;LongName);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serialCont (s-&gt;Commands);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout);
+}
+
+static void cbServiceReady (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CService *s = (CService*) (uint) from-&gt;appId();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;*:*:%d is ready&quot;, s-&gt;Id);
+ &nbsp; &nbsp; &nbsp; &nbsp;s-&gt;Ready = true;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// broadcast the message to the admin service
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SR&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (s-&gt;Id);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout);
+}
+
+static void cbLog (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// received an answer for a command, give it to the AS
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// broadcast the message to the admin service
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;LOG&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;string log;
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (log);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (log);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout);
+}
+
+void serviceConnection (const string &amp;serviceName, TSockId from, void *arg)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;Services.push_back (CService (from));
+ &nbsp; &nbsp; &nbsp; &nbsp;CService *s = &amp;(Services.back());
+ &nbsp; &nbsp; &nbsp; &nbsp;from-&gt;setAppId ((uint64)(uint)s);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;*:*:%d connected&quot;, s-&gt;Id);
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;// broadcast the message to the admin service
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SC&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (s-&gt;Id);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout);
+}
+
+void serviceDisconnection (const string &amp;serviceName, TSockId from, void *arg)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CService *s = (CService*) (uint) from-&gt;appId();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;*:*:%d disconnected&quot;, s-&gt;Id);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// broadcast the message to the admin service
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SD&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (s-&gt;Id);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// remove the service from the list
+ &nbsp; &nbsp; &nbsp; &nbsp;Services.erase (findService(s-&gt;Id));
+}
+
+
+/** Callback Array
+ */
+TCallbackItem ServicesCallbackArray[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;SID&quot;, cbServiceIdentification },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;SR&quot;, cbServiceReady },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;LOG&quot;, cbLog },
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////// CONNECTION TO THE AS ////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void errorMessage(string message, TSockId from)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;ERR&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (message);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout, from);
+}
+
+static void cbExecuteSystemCommand (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;string command;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (command);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;IThread *thread = IThread::create (new CExecuteCommandThread (command));
+ &nbsp; &nbsp; &nbsp; &nbsp;thread-&gt;start ();
+}
+
+static void cbStartService (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;string serviceAlias, command, path;
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (serviceAlias);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;Starting the service alias '%s'&quot;, serviceAlias.c_str());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;try
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;path = IService::ConfigFile.getVar(serviceAlias).asString(0);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;command = IService::ConfigFile.getVar(serviceAlias).asString(1);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;catch(EConfigFile &amp;e)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;error in serviceAlias '%s' in config file (%s)&quot;, serviceAlias.c_str(), e.what());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// give the service alias to the service to forward it back when it will connected to the aes.
+ &nbsp; &nbsp; &nbsp; &nbsp;command += &quot; -n&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp;command += serviceAlias.c_str();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;command += &quot; &gt;NUL:&quot;;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;IThread *thread = IThread::create (new CExecuteServiceThread (serviceAlias, command, path));
+ &nbsp; &nbsp; &nbsp; &nbsp;thread-&gt;start ();
+}
+
+static void cbStopService (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;uint32 sid;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (sid);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;I have to stop service '%s'&quot;);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;SIT sit = findService (sid, false);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (sit == Services.end())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// don't find the aes, send an error message
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;errorMessage (&quot;couldn't stop service, aes didn't find the service&quot;, from);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA(&quot;AES&quot;), &quot;STOPS&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AES&quot;, msgout, (*sit).SockId);
+}
+
+static void cbExecCommand (CMessage&amp; msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;uint32 sid;
+ &nbsp; &nbsp; &nbsp; &nbsp;string command;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (command);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;SIT sit = findService (sid, false);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (sit == Services.end())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// don't find the aes, send an error message
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;errorMessage (&quot;couldn't stop service, aes didn't find the service&quot;, from);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA(&quot;AES&quot;), &quot;EXEC_COMMAND&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (command);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AES&quot;, msgout, (*sit).SockId);
+}
+
+void loadAndSendServicesAliasList (CConfigFile::CVar &amp;var);
+
+void cbASServiceConnection (const string &amp;serviceName, TSockId from, void *arg)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// new admin service, send him all out info about services
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;AS %s is connected&quot;, from-&gt;asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SL&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;uint32 nbs = (uint32)Services.size();
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (nbs);
+ &nbsp; &nbsp; &nbsp; &nbsp;for (SIT sit = Services.begin(); sit != Services.end(); sit++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial ((*sit).Id, (*sit).AliasName, (*sit).ShortName, (*sit).LongName, (*sit).Ready);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serialCont ((*sit).Commands);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout, from);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;loadAndSendServicesAliasList (IService::ConfigFile.getVar (&quot;Services&quot;));
+}
+
+TCallbackItem AESASCallbackArray[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;SYS&quot;, cbExecuteSystemCommand },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;STARTS&quot;, cbStartService },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;STOPS&quot;, cbStopService },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;EXEC_COMMAND&quot;, cbExecCommand },
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////// SERVICE IMPLEMENTATION //////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void loadAndSendServicesAliasList (CConfigFile::CVar &amp;services)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;vector&lt;string&gt; servicesaliaslist;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (sint i = 0 ; i &lt; services.size (); i++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;servicesaliaslist.push_back (services.asString(i));
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout2 (CNetManager::getSIDA (&quot;AESAS&quot;), &quot;SAL&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout2.serialCont (servicesaliaslist);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;AESAS&quot;, msgout2, 0);
+}
+
+
+class CAdminExecutorService : public IService
+{
+public:
+
+ &nbsp; &nbsp; &nbsp; &nbsp;/// Init the service, load the universal time.
+ &nbsp; &nbsp; &nbsp; &nbsp;void &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;init ()
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::setConnectionCallback (&quot;AES&quot;, serviceConnection, NULL);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::setDisconnectionCallback (&quot;AES&quot;, serviceDisconnection, NULL);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// install the server for AS
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::setConnectionCallback (&quot;AESAS&quot;, cbASServiceConnection, NULL);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::addServer (&quot;AESAS&quot;, 49996);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::addCallbackArray (&quot;AESAS&quot;, AESASCallbackArray, sizeof(AESASCallbackArray)/sizeof(AESASCallbackArray[0]));
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConfigFile.setCallback (&quot;Services&quot;, loadAndSendServicesAliasList);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;loadAndSendServicesAliasList (IService::ConfigFile.getVar (&quot;Services&quot;));
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;bool &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;update ()
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return true;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+};
+
+
+/// Naming Service
+NLNET_SERVICE_MAIN (CAdminExecutorService, &quot;AES&quot;, &quot;admin_executor_service&quot;, 49997, ServicesCallbackArray);
+</PRE> \ No newline at end of file