? src/Makefile
Index: src/daemon.cpp
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/daemon.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/daemon.cpp	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/daemon.cpp	29 Apr 2007 20:13:02 -0000	1.2
@@ -26,6 +26,7 @@
 	{
 		int stat;
 		while (waitpid (-1, &stat, WNOHANG) > 0);
+		signal (SigType,SigHandler);
 		return;
 	}
 	switch (SigType)
Index: src/fg_server.cpp
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/fg_server.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.10
diff -u -r1.1.1.1 -r1.10
--- src/fg_server.cpp	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/fg_server.cpp	14 May 2007 20:15:23 -0000	1.10
@@ -13,6 +13,13 @@
 #include "fg_server.hpp"
 #include "typcnvt.hpp"
 
+
+#include <netinet/in.h>
+/* From netSocket.cxx */
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned long)-1)
+#endif
+                                                                                               
 bool    RunAsDaemon = true;
 cDaemon Myself;
 
@@ -314,6 +321,7 @@
         NewPlayer.HasErrors     = true;
         NewPlayer.Error         = ErrorMsg;
         NewPlayer.ClientID      = m_MaxClientID;
+	NewPlayer.LastRelayedToInactive = 0;
         AlreadyThere            = false;
         CurrentPlayer           = m_PlayerList.begin();
         //////////////////////////////////////////////////
@@ -376,6 +384,7 @@
         NewPlayer.IsLocal       = IsLocal;
         NewPlayer.LastPos.clear();
         NewPlayer.LastOrientation.clear();
+	NewPlayer.LastRelayedToInactive = 0;
         if (MsgId == CHAT_MSG_ID)
         {       // don't add to local list
                 return;
@@ -411,6 +420,7 @@
                 Message += m_ServerName;
                 CreateChatMessage (NewPlayer.ClientID , Message);
                 Message = "this is version v" + string(VERSION);
+		Message += " (Experimental features: LazyRelay $Revision: 1.10 $)";
                 CreateChatMessage (NewPlayer.ClientID , Message);
                 Message  ="using protocol version v";
                 Message += NumToStr (m_ProtoMajorVersion, 0);
@@ -440,10 +450,17 @@
 FG_SERVER::AddRelay ( const string & Server, int Port )
 {
         mT_Relay        NewRelay;
+        unsigned int IP;
 
         NewRelay.Name = Server;
         NewRelay.Address.set ((char*) Server.c_str(), Port);
-        m_RelayList.push_back (NewRelay);
+        IP = NewRelay.Address.getIP();
+        if ( IP != INADDR_ANY && IP != INADDR_NONE )
+        {
+                NewRelay.Timestamp = time(0);
+                NewRelay.Active = false;
+                m_RelayList.push_back (NewRelay);
+        }
 } // FG_SERVER::AddRelay()
 //////////////////////////////////////////////////////////////////////
 
@@ -458,6 +475,7 @@
 {
         time_t          Timestamp;
         mT_PlayerListIt CurrentPlayer;
+	mT_RelayListIt  CurrentRelay;
 
         Timestamp = time(0);
         CurrentPlayer = m_PlayerList.begin();
@@ -486,6 +504,17 @@
                 }
                 CurrentPlayer++;
         }
+        CurrentRelay = m_RelayList.begin();
+        while (CurrentRelay != m_RelayList.end())
+        {
+               if (((Timestamp-CurrentRelay->Timestamp) > RELAY_TTL) && CurrentRelay->Active)
+                {
+                       CurrentRelay->Active = false;
+                       m_Log.log (L_HIGH) << "Deactivating relay " << CurrentRelay->Name << endl;
+               }
+               CurrentRelay++;
+       }
+        
 } // FG_SERVER::CleanUp ()
 //////////////////////////////////////////////////////////////////////
 
@@ -548,6 +577,7 @@
         Point3D                 SenderPosition;
         Point3D                 SenderOrientation;
         mT_PlayerListIt         CurrentPlayer;
+        mT_PlayerListIt         SendingPlayer;
         mT_RelayListIt          CurrentRelay;
         mT_MessageIt            CurrentMessage;
 
@@ -660,7 +690,7 @@
         }
         if (PlayerInList == false)
         {
-                AddClient (SenderAddress, Msg, PacketFromLocalClient);
+		AddClient (SenderAddress, Msg, PacketFromLocalClient);
         }
         //////////////////////////////////////////
         //
@@ -716,6 +746,7 @@
                 if ((CurrentPlayer->Callsign == MsgHdr->Callsign)
                 && (CurrentPlayer->Address.getIP() == SenderAddress.getIP()))
                 {
+			SendingPlayer = CurrentPlayer;
                         CurrentPlayer++;
                         continue; // don't send packet back to sender
                 }
@@ -810,16 +841,37 @@
         //        a Relay
         //
         //////////////////////////////////////////////////
+	bool UpdateInactive = Timestamp-SendingPlayer->LastRelayedToInactive > UPDATE_INACTIVE_PERIOD;
+	if (UpdateInactive) {
+		SendingPlayer->LastRelayedToInactive = Timestamp;
+	}
         if (PacketFromLocalClient)
         {
                 MsgHdr->Magic = XDR_encode_uint32 (RELAY_MAGIC);
                 CurrentRelay = m_RelayList.begin();
                 while (CurrentRelay != m_RelayList.end())
                 {
-                        m_DataSocket->sendto(Msg, Bytes, 0,
-                          &CurrentRelay->Address);
-                        CurrentRelay++;
-                }
+                       	if ((CurrentRelay->Active && IsInRange(*CurrentRelay, *SendingPlayer)) || UpdateInactive) {   
+                               	m_DataSocket->sendto(Msg, Bytes, 0, &CurrentRelay->Address);
+				// cerr << '.';  // For debugging.
+                       	}
+                	CurrentRelay++;
+               }
+        } else {
+               // Renew timestamp of sending relay.
+               mT_RelayListIt CurrentRelay = m_RelayList.begin();
+               while (CurrentRelay != m_RelayList.end())
+               {
+                       if (CurrentRelay->Address.getIP() == SenderAddress.getIP()) {
+                               if (!CurrentRelay->Active) {
+                                       m_Log.log (L_HIGH) << "Activating relay " << CurrentRelay->Name  << endl;
+                                       CurrentRelay->Active = true;
+                               }
+                               CurrentRelay->Timestamp = Timestamp;
+                               break;
+                       }
+                       CurrentRelay++;
+           	}
         }
 } // FG_SERVER::HandlePacket ( char* sMsg[MAX_PACKET_SIZE] )
 //////////////////////////////////////////////////////////////////////
@@ -836,6 +888,7 @@
         char            Msg[MAX_PACKET_SIZE];
         netAddress      SenderAddress;
         netSocket*      ListenSockets[3 + MAX_TELNETS];
+	time_t          CurrentTime, LastCleanUp;
 
         m_IsParent = true;
         if (m_Listening == false)
@@ -850,8 +903,10 @@
         //
         //////////////////////////////////////////////////
         CreateChatMessage (0, string("server ")+m_ServerName+string(" is online"));
+	LastCleanUp = time(0);
         for (;;)
         {
+		CurrentTime = time(0);
                 errno = 0;
                 ListenSockets[0] = m_DataSocket;
                 ListenSockets[1] = m_TelnetSocket;
@@ -860,6 +915,7 @@
                 if (Bytes == -2)
                 {       // timeout, no packets received
                         CleanUp ();
+			LastCleanUp = CurrentTime;
                         continue;
                 }
                 if (! Bytes)
@@ -886,8 +942,15 @@
                 else if (ListenSockets[1] != 0)
                 {       // something on the wire (telnet)
                         HandleTelnet (m_TelnetSocket);
+			LastCleanUp = CurrentTime;
                         CleanUp ();
                 } // TelnetSocket
+               
+               // Do periodic CleanUp.
+               if ((CurrentTime-LastCleanUp > PLAYER_TTL) || (CurrentTime-LastCleanUp > RELAY_TTL)) {
+                       CleanUp ();
+                       LastCleanUp = CurrentTime;
+               }
         }
 } // FG_SERVER::Loop()
 //////////////////////////////////////////////////////////////////////
@@ -1028,3 +1091,26 @@
 } // FG_SERVER::Done()
 //////////////////////////////////////////////////////////////////////
 
+
+//////////////////////////////////////////////////////////////////////
+//
+//      Decides whether the relay is interested in full rate updates
+//
+//////////////////////////////////////////////////////////////////////
+bool
+FG_SERVER::IsInRange( mT_Relay& Relay,  mT_Player& SendingPlayer )
+{
+        mT_PlayerListIt         CurrentPlayer;
+
+        CurrentPlayer = m_PlayerList.begin();
+        while (CurrentPlayer != m_PlayerList.end()) {
+		if ((CurrentPlayer->Address.getIP() == Relay.Address.getIP()) &&
+		    (Distance (SendingPlayer.LastPos, CurrentPlayer->LastPos) <= m_PlayerIsOutOfReach)) {
+			return true;
+		}
+		CurrentPlayer++;
+	}
+
+	return false;
+} // FG_SERVER::IsInRange()
+//////////////////////////////////////////////////////////////////////
Index: src/fg_server.hpp
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/fg_server.hpp,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- src/fg_server.hpp	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/fg_server.hpp	13 May 2007 12:00:20 -0000	1.4
@@ -19,7 +19,11 @@
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#ifdef __sparc
+#include <sys/int_types.h>
+#else
 #include <stdint.h>
+#endif
 #include <unistd.h>
 #include "netSocket.h"
 #include "logobject.hpp"
@@ -53,6 +57,8 @@
 		// other constants
 		MAX_PACKET_SIZE		= 1024,
 		PLAYER_TTL		= 10,
+		RELAY_TTL               = 10,
+		UPDATE_INACTIVE_PERIOD  = 1,
 		MAX_TELNETS		= 5,
 		RELAY_MAGIC		= 0x53464746    // GSGF
 	};
@@ -103,6 +109,7 @@
 		string		Error;		// in case of errors
 		bool		HasErrors;
 		int		ClientID;
+		time_t		LastRelayedToInactive;
 	}; // mT_Player
 
 	//////////////////////////////////////////////////
@@ -115,6 +122,8 @@
 	public:
 		string		Name;
 		netAddress	Address;
+		time_t          Timestamp;
+		bool            Active;
 	};
 	//////////////////////////////////////////////////
 	//
@@ -141,6 +150,7 @@
 			netAddress &SenderAdress );
 	void	CleanUp();
 	void	CreateChatMessage ( int ID, string Msg );
+	bool    IsInRange( mT_Relay& Relay,  mT_Player& SendingPlayer );
 	//////////////////////////////////////////////////
 	//
 	//	private variables
Index: src/main.cpp
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/main.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/main.cpp	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/main.cpp	29 Apr 2007 17:41:28 -0000	1.2
@@ -1,6 +1,9 @@
 using namespace std;
 
 #include <cstdlib>
+#ifdef __sparc
+#include <signal.h>
+#endif
 #include "fg_server.hpp"
 #include "fg_config.hpp"
 #include "daemon.hpp"
Index: src/netSocket.cxx
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/netSocket.cxx,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/netSocket.cxx	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/netSocket.cxx	13 May 2007 12:09:23 -0000	1.2
@@ -18,7 +18,7 @@
  
      For further information visit http://plib.sourceforge.net
 
-     $Id: netSocket.cxx,v 1.1.1.1 2007-04-29 17:01:22 anders Exp $
+     $Id: netSocket.cxx,v 1.2 2007-05-13 12:09:23 anders Exp $
 */
 
 #include "netSocket.h"
@@ -91,7 +91,7 @@
       	memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ;
       else
       {
-        perror ( "netAddress::set" ) ;
+        herror ( "netAddress::set" ) ;
         sin_addr = INADDR_ANY ;
       }
     }
Index: src/tiny_xdr.hxx
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/tiny_xdr.hxx,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/tiny_xdr.hxx	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/tiny_xdr.hxx	29 Apr 2007 17:41:28 -0000	1.2
@@ -19,7 +19,7 @@
 #endif
 #ifdef HAVE_STDINT_H
 #   include <stdint.h>
-#elif defined( _MSC_VER ) || defined(__MINGW32__) || defined(sun)
+#elif defined( _MSC_VER ) || defined(__MINGW32__)
 typedef signed char        int8_t;
 typedef signed short       int16_t;
 typedef signed int         int32_t;
@@ -28,6 +28,8 @@
 typedef unsigned short     uint16_t;
 typedef unsigned int       uint32_t;
 typedef unsigned __int64   uint64_t;
+#elif defined(__sparc)
+#include <sys/int_types.h>
 #else
 #   error
 #   error "Port me! Platforms that don't have <stdint.h> need to define int8_t, et. al."
@@ -52,6 +54,11 @@
 #           define __BYTE_ORDER __BIG_ENDIAN
 #   endif
 
+#elif defined __sparc
+#   ifndef __BYTE_ORDER
+#           define __BYTE_ORDER __BIG_ENDIAN
+#   endif
+
 #elif defined(__CYGWIN__) || defined(_WIN32)
 #   ifndef __BYTE_ORDER
 #           define __BYTE_ORDER __LITTLE_ENDIAN
@@ -89,7 +96,7 @@
             ((b&0x0000ff00)<<8)|((b&0x000000ff)<<24);
 }
 
-inline uint64_t bswap_64(unsignedlonglong b) {
+inline uint64_t bswap_64(uint64_t b) {
     return ( ((b&0xff00000000000000LL) >> 56) |
              ((b&0x00ff000000000000LL) >> 40) |
              ((b&0x0000ff0000000000LL) >> 24) |
Index: src/typcnvt.hpp
===================================================================
RCS file: /home/cvs/anders/FlightGear/fgmp/fg_server/src/typcnvt.hpp,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/typcnvt.hpp	29 Apr 2007 17:01:22 -0000	1.1.1.1
+++ src/typcnvt.hpp	29 Apr 2007 17:41:28 -0000	1.2
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////
 //
-// $Id: typcnvt.hpp,v 1.1.1.1 2007-04-29 17:01:22 anders Exp $
+// $Id: typcnvt.hpp,v 1.2 2007-04-29 17:41:28 anders Exp $
 //
 //////////////////////////////////////////////////////////////////////
 #ifndef TYPCNVTHDR
@@ -198,7 +198,7 @@
         else
         {
             n = n_Factor;
-            n_WorkNumber = abs(n_WorkNumber);
+            n_WorkNumber = abs((long int)n_WorkNumber);
             while (n_WorkNumber >= 0 && n > 1)
             {
                 str_Return = Numbers[n_WorkNumber % n_Base] + str_Return;
