aboutsummaryrefslogtreecommitdiff
path: root/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
committerneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
commit0ea5fc66924303d1bf73ba283a383e2aadee02f2 (patch)
tree2568e71a7ccc44ec23b8bb3f0ff97fb6bf2ed709 /cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date
downloadnevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.tar.xz
nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.zip
Initial commit
Diffstat (limited to 'cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date')
-rw-r--r--cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html569
1 files changed, 569 insertions, 0 deletions
diff --git a/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html b/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html
new file mode 100644
index 00000000..8f7e28a2
--- /dev/null
+++ b/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html
@@ -0,0 +1,569 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
+<HEAD><style> A { color:black }</style>
+<!-- hennerik CVSweb $Revision: 1.93 $ -->
+<TITLE>code/nel/src/net/naming_client.cpp - view - 1.48</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee">
+<table width="100%" border=0 cellspacing=0 cellpadding=1 bgcolor="#aaaaaa"><tr valign=bottom><td><a href="naming_client.cpp?sortby=date"><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="naming_client.cpp?sortby=date">naming_client.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/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a></b></td></tr></table><HR noshade><table width="100%"><tr><td bgcolor="#ffffff">File: <a href="/cvs/cvsweb.cgi/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?sortby=date">naming_client.cpp</a>&nbsp;(<A HREF="/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/naming_client.cpp?rev=1.48&amp;sortby=date" target="cvs_checkout" onClick="window.open('/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/naming_client.cpp?rev=1.48','cvs_checkout','resizeable,scrollbars');"><b>download</b></A>)<BR>
+Revision <B>1.48</B>, <i>Thu Jul 18 15:00:43 2002 UTC</i> (10 days, 18 hours ago) by <i>lecroart</i>
+<BR>Branch: <b>MAIN</b>
+<BR>CVS Tags: <b>HEAD</b><BR>Changes since <b>1.47: +15 -1
+ lines</b><PRE>
+ADDED: quit if the NS ask it
+</PRE>
+</td></tr></table><HR noshade><PRE>/** \file naming_client.cpp
+ * CNamingClient
+ *
+ * $Id: naming_client.cpp,v 1.48 2002/07/18 15:00:43 lecroart Exp $
+ *
+ */
+
+/* Copyright, 2000 Nevrax Ltd.
+ *
+ * This file is part of NEVRAX NEL.
+ * NEVRAX NEL 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 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; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+//
+// Includes
+//
+
+#include &quot;stdnet.h&quot;
+
+#include &quot;nel/net/naming_client.h&quot;
+#include &quot;nel/net/callback_client.h&quot;
+#include &quot;nel/net/service.h&quot;
+
+
+//
+// Namespaces
+//
+
+using namespace std;
+using namespace NLMISC;
+
+
+namespace NLNET {
+
+//
+// Variables
+//
+
+CCallbackClient *CNamingClient::_Connection = NULL;
+CNamingClient::TRegServices CNamingClient::_RegisteredServices;
+
+static TBroadcastCallback _RegistrationBroadcastCallback = NULL;
+static TBroadcastCallback _UnregistrationBroadcastCallback = NULL;
+
+uint &nbsp; &nbsp;CNamingClient::_ThreadId = 0xFFFFFFFF;
+
+TServiceId CNamingClient::_MySId = 0;
+
+
+std::list&lt;CNamingClient::CServiceEntry&gt; CNamingClient::RegisteredServices;
+NLMISC::CMutex CNamingClient::RegisteredServicesMutex(&quot;CNamingClient::RegisteredServicesMutex&quot;);
+
+void CNamingClient::setRegistrationBroadcastCallback (TBroadcastCallback cb)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;_RegistrationBroadcastCallback = cb; &nbsp; &nbsp; &nbsp; &nbsp;
+}
+
+void CNamingClient::setUnregistrationBroadcastCallback (TBroadcastCallback cb)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;_UnregistrationBroadcastCallback = cb; &nbsp; &nbsp; &nbsp; &nbsp;
+}
+
+//
+
+//
+
+static bool Registered;
+static TServiceId RegisteredSuccess;
+static TServiceId RegisteredSID;
+
+static void cbRegister (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (RegisteredSuccess);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (RegisteredSuccess) msgin.serial (RegisteredSID);
+ &nbsp; &nbsp; &nbsp; &nbsp;Registered = true;
+}
+
+//
+
+static bool QueryPort;
+static uint16 QueryPortPort;
+
+static void cbQueryPort (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (QueryPortPort);
+ &nbsp; &nbsp; &nbsp; &nbsp;QueryPort = true;
+}
+
+//
+
+static bool FirstRegisteredBroadcast;
+
+void cbRegisterBroadcast (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;TServiceId size;
+ &nbsp; &nbsp; &nbsp; &nbsp;string name;
+ &nbsp; &nbsp; &nbsp; &nbsp;TServiceId sid;
+ &nbsp; &nbsp; &nbsp; &nbsp;CInetAddress addr;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (size);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;for (TServiceId i = 0; i &lt; size; i++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (name);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (addr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// add it in the list
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;std::vector&lt;CInetAddress&gt; addrs;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::find (sid, addrs);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (addrs.size() == 0)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.enter ();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServices.push_back (CNamingClient::CServiceEntry (name, sid, addr));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.leave ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;NC: Registration Broadcast of the service %s-%hu '%s'&quot;, name.c_str(), (uint16)sid, addr.asString().c_str());
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (_RegistrationBroadcastCallback != NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_RegistrationBroadcastCallback (name, sid, addr);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else if (addrs.size() == 1)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.enter ();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (std::list&lt;CNamingClient::CServiceEntry&gt;::iterator it = CNamingClient::RegisteredServices.begin(); it != CNamingClient::RegisteredServices.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (sid == (*it).SId)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(*it).Name = name;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(*it).Addr = addr;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.leave ();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;NC: Registration Broadcast (update) of the service %s-%hu '%s'&quot;, name.c_str(), (uint16)sid, addr.asString().c_str());
+ &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlstop;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;FirstRegisteredBroadcast = true;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;//CNamingClient::displayRegisteredServices ();
+}
+ &nbsp; &nbsp; &nbsp; &nbsp;
+//
+
+void cbUnregisterBroadcast (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;string name;
+ &nbsp; &nbsp; &nbsp; &nbsp;TServiceId sid;
+ &nbsp; &nbsp; &nbsp; &nbsp;CInetAddress addr;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (name);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (addr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// remove it in the list, if the service is not found, ignore it
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.enter ();
+ &nbsp; &nbsp; &nbsp; &nbsp;for (std::list&lt;CNamingClient::CServiceEntry&gt;::iterator it = CNamingClient::RegisteredServices.begin(); it != CNamingClient::RegisteredServices.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*it).SId == sid)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// check the structure
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlassertex ((*it).Name == name, (&quot;%s %s&quot;,(*it).Name.c_str(), name.c_str()));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlassertex ((*it).Addr == addr, (&quot;%d %d&quot;,(*it).Addr.asString().c_str(), addr.asString().c_str()));
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServices.erase (it);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.leave ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;NC: Unregistration Broadcast of the service %s-%hu&quot;, name.c_str(), (uint16)sid);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// send the ACK to the NS
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNamingClient::_Connection-&gt;getSIDA(), &quot;ACK_UNI&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::_Connection-&gt;send (msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// oh my god, it s my sid! but i m alive, why this f*cking naming service want to kill me? ok, i leave it alone!
+ &nbsp; &nbsp; &nbsp; &nbsp;if(CNamingClient::_MySId == sid)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;Naming Service asked me to leave, I leave!&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IService::getInstance()-&gt;exit();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (_UnregistrationBroadcastCallback != NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_UnregistrationBroadcastCallback (name, sid, addr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;//CNamingClient::displayRegisteredServices ();
+}
+
+//
+
+static TCallbackItem NamingClientCallbackArray[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;RG&quot;, cbRegister },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;QP&quot;, cbQueryPort },
+
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;RGB&quot;, cbRegisterBroadcast },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;UNB&quot;, cbUnregisterBroadcast },
+};
+
+void CNamingClient::connect( const CInetAddress &amp;addr, CCallbackNetBase::TRecordingState rec )
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection == NULL || _Connection != NULL &amp;&amp; !_Connection-&gt;connected ());
+ &nbsp; &nbsp; &nbsp; &nbsp;_ThreadId = getThreadId ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (_Connection == NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection = new CCallbackClient( rec, &quot;naming_client.nmr&quot; );
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;addCallbackArray (NamingClientCallbackArray, sizeof (NamingClientCallbackArray) / sizeof (NamingClientCallbackArray[0]));
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;connect (addr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// now we are connected, clear the old registered service table
+/*
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.enter ();
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServices.clear ();
+ &nbsp; &nbsp; &nbsp; &nbsp;CNamingClient::RegisteredServicesMutex.leave ();
+*/
+ &nbsp; &nbsp; &nbsp; &nbsp;// wait the message that contains all already connected services
+
+ &nbsp; &nbsp; &nbsp; &nbsp;FirstRegisteredBroadcast = false;
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!FirstRegisteredBroadcast &amp;&amp; _Connection-&gt;connected ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;update (-1);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlSleep (1);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+
+void CNamingClient::disconnect ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;if (_Connection != NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (_Connection-&gt;connected ())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;disconnect ();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;delete _Connection;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection = NULL;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// we don't call unregisterAllServices because when the naming service will see the disconnection,
+ &nbsp; &nbsp; &nbsp; &nbsp;// it'll automatically unregister all services registered by this client.
+}
+
+string CNamingClient::info ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;string res;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (connected ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;res = &quot;connected to &quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;res += _Connection-&gt;remoteAddress().asString();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;res = &quot;Not connected&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return res;
+}
+
+TServiceId CNamingClient::registerService (const std::string &amp;name, const CInetAddress &amp;addr)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (_Connection-&gt;getSIDA(), &quot;RG&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;std::string&amp;&gt;(name));
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;CInetAddress&amp;&gt;(addr));
+ &nbsp; &nbsp; &nbsp; &nbsp;TServiceId sid = 0;
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;send (msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// wait the answer of the naming service &quot;RG&quot;
+ &nbsp; &nbsp; &nbsp; &nbsp;Registered = false;
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!Registered)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;update (-1);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlSleep (1);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (RegisteredSuccess)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_MySId = RegisteredSID;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_RegisteredServices.insert (make_pair (RegisteredSID, name));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nldebug (&quot;NC: Registered service %s-%hu at %s&quot;, name.c_str(), (uint16)RegisteredSID, addr.asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlerror (&quot;NC: Naming service refused to register service %s at %s&quot;, name.c_str(), addr.asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return RegisteredSID;
+}
+
+bool CNamingClient::registerServiceWithSId (const std::string &amp;name, const CInetAddress &amp;addr, TServiceId sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (_Connection-&gt;getSIDA(), &quot;RG&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;std::string&amp;&gt;(name));
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;CInetAddress&amp;&gt;(addr));
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;send (msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// wait the answer of the naming service &quot;RGI&quot;
+ &nbsp; &nbsp; &nbsp; &nbsp;Registered = false;
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!Registered)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;update (-1);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlSleep (1);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (RegisteredSuccess)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_MySId = sid;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_RegisteredServices.insert (make_pair (RegisteredSID, name));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nldebug (&quot;NC: Registered service with sid %s-%hu at %s&quot;, name.c_str(), (uint16)RegisteredSID, addr.asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlerror (&quot;NC: Naming service refused to register service with sid %s at %s&quot;, name.c_str(), addr.asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return RegisteredSuccess == 1;
+}
+
+void CNamingClient::resendRegisteration (const std::string &amp;name, const CInetAddress &amp;addr, TServiceId sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (_Connection-&gt;getSIDA(), &quot;RRG&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;std::string&amp;&gt;(name));
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (const_cast&lt;CInetAddress&amp;&gt;(addr));
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;send (msgout);
+}
+
+void CNamingClient::unregisterService (TServiceId sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (_Connection-&gt;getSIDA(), &quot;UNI&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;send (msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nldebug (&quot;NC: Unregistering service %s-%hu&quot;, _RegisteredServices[sid].c_str(), sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;_RegisteredServices.erase (sid);
+}
+
+void CNamingClient::unregisterAllServices ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!_RegisteredServices.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TRegServices::iterator irs = _RegisteredServices.begin();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TServiceId sid = (*irs).first;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unregisterService (sid);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+uint16 CNamingClient::queryServicePort ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (_Connection-&gt;getSIDA(), &quot;QP&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;send (msgout);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// wait the answer of the naming service &quot;QP&quot;
+ &nbsp; &nbsp; &nbsp; &nbsp;QueryPort = false;
+ &nbsp; &nbsp; &nbsp; &nbsp;while (!QueryPort)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;update (-1);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlSleep (1);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;NC: Received the answer of the query port (%hu)&quot;, QueryPortPort);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return QueryPortPort;
+}
+
+bool CNamingClient::lookup (const std::string &amp;name, CInetAddress &amp;addr)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;vector&lt;CInetAddress&gt; addrs;
+ &nbsp; &nbsp; &nbsp; &nbsp;find (name, addrs);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (addrs.size()==0)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (addrs.size()==1);
+ &nbsp; &nbsp; &nbsp; &nbsp;addr = addrs[0];
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+bool CNamingClient::lookup (TServiceId sid, CInetAddress &amp;addr)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;vector&lt;CInetAddress&gt; addrs;
+ &nbsp; &nbsp; &nbsp; &nbsp;find (sid, addrs);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (addrs.size()==0)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (addrs.size()==1);
+ &nbsp; &nbsp; &nbsp; &nbsp;addr = addrs[0];
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+/// \todo ace: now the lookupAlternate doesn't say to the naming service that this addr is bad so the NS can't remove it from his list. find a solution
+bool CNamingClient::lookupAlternate (const std::string &amp;name, CInetAddress &amp;addr)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// remove it from his local list
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;RegisteredServicesMutex.enter ();
+ &nbsp; &nbsp; &nbsp; &nbsp;for (std::list&lt;CServiceEntry&gt;::iterator it = RegisteredServices.begin(); it != RegisteredServices.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*it).Addr == addr)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RegisteredServices.erase (it);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;RegisteredServicesMutex.leave ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;vector&lt;CInetAddress&gt; addrs;
+ &nbsp; &nbsp; &nbsp; &nbsp;find (name, addrs);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (addrs.size()==0)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (addrs.size()==1);
+ &nbsp; &nbsp; &nbsp; &nbsp;addr = addrs[0];
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+void CNamingClient::lookupAll (const std::string &amp;name, std::vector&lt;CInetAddress&gt; &amp;addrs)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;find (name, addrs);
+}
+
+bool CNamingClient::lookupAndConnect (const std::string &amp;name, CCallbackClient &amp;sock)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlassert (_Connection != NULL &amp;&amp; _Connection-&gt;connected ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// look up for service
+ &nbsp; &nbsp; &nbsp; &nbsp;CInetAddress servaddr;
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;// if service not found, return false
+ &nbsp; &nbsp; &nbsp; &nbsp;if (!CNamingClient::lookup (name, servaddr))
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;do
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// try to connect to the server
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sock.connect (servaddr);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// connection succeeded
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return true;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;catch (ESocketConnectionFailed &amp;e)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nldebug( &quot;Connection to %s failed: %s, tring another service if available&quot;, servaddr.asString().c_str(), e.what() );
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// try another server and if service is not found, return false
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!CNamingClient::lookupAlternate (name, servaddr))
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;while (true);
+}
+
+
+
+void CNamingClient::update ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;checkThreadId ();
+ &nbsp; &nbsp; &nbsp; &nbsp;// get message for naming service (new registration for example)
+ &nbsp; &nbsp; &nbsp; &nbsp;if (_Connection != NULL &amp;&amp; _Connection-&gt;connected ())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_Connection-&gt;update ();
+}
+
+void CNamingClient::checkThreadId ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if (getThreadId () != _ThreadId)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlerror (&quot;You try to access to the CNamingClient with 2 differents thread (%d and %d)&quot;, _ThreadId, getThreadId());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+
+//
+// Commands
+//
+
+NLMISC_COMMAND(services, &quot;displays registered services&quot;, &quot;&quot;)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if(args.size() != 0) return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;Display the %d registered services :&quot;, CNamingClient::getRegisteredServices().size());
+ &nbsp; &nbsp; &nbsp; &nbsp;for (std::list&lt;CNamingClient::CServiceEntry&gt;::const_iterator it = CNamingClient::getRegisteredServices().begin(); it != CNamingClient::getRegisteredServices().end(); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot; &gt; %s-%hu '%s'&quot;, (*it).Name.c_str(), (uint16)(*it).SId, (*it).Addr.asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;End ot the list&quot;);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+} // NLNET
+</PRE> \ No newline at end of file