2011-02-06 13:57 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)

* contrib/hbnetio/utils/hbnetio/netiosrv.prg
  * contrib/hbnetio/utils/hbnetio/netiocon.prg
    + Resolved remaining TODOs regarding client notifications.
    + Added automatic deletion of (abnormally) disconnected clients
      from notification list.
    * Commented filter code dealing with host names until we find
      out how to get those from IP.

  * contrib/hbhttpd/core.prg
    ! English translation of one word.

  * contrib/hbformat/hbformat.prg
    ! Added missing ASCAN() from list of functions.
This commit is contained in:
Viktor Szakats
2011-02-06 12:58:09 +00:00
parent 8ab2bf32b2
commit c9fece796d
5 changed files with 107 additions and 73 deletions

View File

@@ -16,6 +16,21 @@
The license applies to all entries newer than 2009-04-28.
*/
2011-02-06 13:57 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
* contrib/hbnetio/utils/hbnetio/netiosrv.prg
* contrib/hbnetio/utils/hbnetio/netiocon.prg
+ Resolved remaining TODOs regarding client notifications.
+ Added automatic deletion of (abnormally) disconnected clients
from notification list.
* Commented filter code dealing with host names until we find
out how to get those from IP.
* contrib/hbhttpd/core.prg
! English translation of one word.
* contrib/hbformat/hbformat.prg
! Added missing ASCAN() from list of functions.
2011-02-06 11:14 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
* contrib/hbrunext/hbrunext.hbp
* contrib/hbrunext/pullext.prg

View File

@@ -176,7 +176,7 @@ METHOD New( aParams, cIniName ) CLASS HBFORMATCODE
ENDIF
IF ! ( ",STR," $ Upper( ::cFunctions ) )
::cFunctions += "AAdd,Abs,AChoice,AClone,ACopy,ADel,ADir,AEval,AFields,AFill,AIns,Alert,Alias,AllTrim,AltD," +;
"Array,Asc,ASize,ASort,At,Bin2I,Bin2L,Bin2W,Bof,Browse,CDow,Chr,CMonth,Col,CToD,CurDir," +;
"Array,Asc,AScan,ASize,ASort,At,Bin2I,Bin2L,Bin2W,Bof,Browse,CDow,Chr,CMonth,Col,CToD,CurDir," +;
"Date,Day,dbAppend,dbClearFil,dbClearInd,dbCloseAll,dbCloseArea,dbCommit,dbCreate,dbDelete,dbEdit,dbEval,Dbf,dbFilter,dbGoBottom,dbGoto,dbRecall,dbReindex,dbRelation,dbRLock,dbRSelect,dbRunLock," +;
"dbSeek,dbSelectArea,dbSetDriver,dbSetFilter,dbSetIndex,dbSetOrder,dbSetRelat,dbSkip,dbStruct,dbUnlock,dbUseArea,Deleted,Descend,DevOut,DevPos," +;
"Directory,DiskSpace,DispBegin,DispBox,DispCount,DispEnd,DispOut,DosError,Dow,Dtoc,Dtos,Empty,Eof,ErrorBlock,ErrorLevel,Eval,Exp,FClose,FCount,FCreate,FErase,FError,FieldBlock,FieldGet,FieldName," +;

View File

@@ -645,7 +645,7 @@ STATIC FUNCTION HttpDateUnformat( cDate, tDate )
// TODO: support outdated compatibility format RFC2616
IF Len( cDate ) == 29 .AND. Right( cDate, 4 ) == " GMT" .AND. SubStr( cDate, 4, 2 ) == ", "
nMonth := ASCAN( { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", ;
nMonth := AScan( { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", ;
"Oct", "Nov", "Dec" }, SubStr( cDate, 9, 3 ) )
IF nMonth > 0
tDate := HB_STOT( SubStr( cDate, 13, 4 ) + PadL( nMonth, 2, "0" ) + SubStr( cDate, 6, 2 ) + ;
@@ -681,7 +681,7 @@ STATIC FUNCTION GetErrorDesc( oErr )
ENDIF
IF !Empty( oErr:description ); cRet += "Description: " + oErr:description + hb_eol()
ENDIF
IF !Empty( oErr:operation ); cRet += "Operacija: " + oErr:operation + hb_eol()
IF !Empty( oErr:operation ); cRet += "Operation: " + oErr:operation + hb_eol()
ENDIF
IF !Empty( oErr:osCode ); cRet += "OS error: " + hb_ntos( oErr:osCode ) + hb_eol()
ENDIF
@@ -776,7 +776,7 @@ FUNCTION UGetHeader( cType )
LOCAL nI
IF ( nI := ASCAN( t_aHeader, {|x| Upper( x[ 1 ] ) == Upper( cType ) } ) ) > 0
IF ( nI := AScan( t_aHeader, {|x| Upper( x[ 1 ] ) == Upper( cType ) } ) ) > 0
RETURN t_aHeader[ nI, 2 ]
ENDIF
@@ -786,7 +786,7 @@ PROCEDURE UAddHeader( cType, cValue )
LOCAL nI
IF ( nI := ASCAN( t_aHeader, {|x| Upper( x[ 1 ] ) == Upper( cType ) } ) ) > 0
IF ( nI := AScan( t_aHeader, {|x| Upper( x[ 1 ] ) == Upper( cType ) } ) ) > 0
t_aHeader[ nI, 2 ] := cValue
ELSE
AAdd( t_aHeader, { cType, cValue } )
@@ -966,7 +966,7 @@ PROCEDURE UProcFiles( cFileName, lIndex )
URedirect( "http://" + server[ "HTTP_HOST" ] + server[ "SCRIPT_NAME" ] + "/" )
RETURN
ENDIF
IF ASCAN( { "index.html", "index.htm" }, ;
IF AScan( { "index.html", "index.htm" }, ;
{|x| iif( HB_FileExists( UOSFileName(cFileName + X ) ), ( cFileName += X, .T. ), .F. ) } ) > 0
UAddHeader( "Content-Type", "text/html" )
UWrite( HB_MEMOREAD( UOsFileName(cFileName ) ) )

View File

@@ -189,7 +189,7 @@ PROCEDURE hbnetiocon_cmdUI( cIP, nPort, cPassword )
IF ! Empty( pConnection )
netio_OpenItemStream( pConnection, "hbnetiomgm_cargo", NIL )
netio_OpenItemStream( pConnection, "hbnetiomgm_regnotif", .F. )
pConnection := NIL
IF lQuit
@@ -214,7 +214,7 @@ PROCEDURE hbnetiocon_IPPortSplit( cAddr, /* @ */ cIP, /* @ */ nPort )
RETURN
/* connect to the server */
/* connect to server */
STATIC FUNCTION ConnectLow( cIP, nPort, cPassword, /* @ */ nStreamID )
LOCAL pConnection
@@ -226,7 +226,7 @@ STATIC FUNCTION ConnectLow( cIP, nPort, cPassword, /* @ */ nStreamID )
IF ! Empty( pConnection )
netio_funcexec( pConnection, "hbnetiomgm_setclientinfo", MyClientInfo() )
nStreamID := netio_OpenItemStream( pConnection, "hbnetiomgm_cargo", "netiocui" )
nStreamID := netio_OpenItemStream( pConnection, "hbnetiomgm_regnotif", .T. )
QQOut( "Connected.", hb_eol() )
ELSE
@@ -264,7 +264,7 @@ STATIC FUNCTION GetPassword()
ATail( GetList ):display()
SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) )
bKeyPaste := SetKey( K_ALT_V, {|| hb_gtInfo( HB_GTI_CLIPBOARDPASTE )})
bKeyPaste := SetKey( K_ALT_V, {|| hb_gtInfo( HB_GTI_CLIPBOARDPASTE ) } )
READ

View File

@@ -75,7 +75,9 @@ REQUEST HB_MT
#define _NETIOSRV_hAllow 15
#define _NETIOSRV_hBlock 16
#define _NETIOSRV_mtxFilters 17
#define _NETIOSRV_MAX_ 17
#define _NETIOSRV_hNotifStream 18
#define _NETIOSRV_mtxNotifStream 19
#define _NETIOSRV_MAX_ 19
#define _NETIOSRV_CONN_pConnection 1
#define _NETIOSRV_CONN_nThreadID 2
@@ -83,10 +85,6 @@ REQUEST HB_MT
#define _NETIOSRV_CONN_hInfo 4
#define _NETIOSRV_CONN_MAX_ 4
/* TODO: Move this to some local data structure */
STATIC s_hConnStream := { => }
STATIC s_mtxConnStream := hb_mutexCreate()
PROCEDURE Main( ... )
LOCAL netiosrv[ _NETIOSRV_MAX_ ]
LOCAL netiomgm[ _NETIOSRV_MAX_ ]
@@ -105,35 +103,37 @@ PROCEDURE Main( ... )
HB_Logo()
netiosrv[ _NETIOSRV_cName ] := "Data"
netiosrv[ _NETIOSRV_nPort ] := _NETIOSRV_PORT_DEF
netiosrv[ _NETIOSRV_cIFAddr ] := _NETIOSRV_IPV4_DEF
netiosrv[ _NETIOSRV_cRootDir ] := hb_dirBase()
netiosrv[ _NETIOSRV_lRPC ] := .F.
netiosrv[ _NETIOSRV_lEncryption ] := .F.
netiosrv[ _NETIOSRV_lAcceptConn ] := .T.
netiosrv[ _NETIOSRV_lShowConn ] := .F.
netiosrv[ _NETIOSRV_lQuit ] := .F.
netiosrv[ _NETIOSRV_hConnection ] := { => }
netiosrv[ _NETIOSRV_mtxConnection ] := hb_mutexCreate()
netiosrv[ _NETIOSRV_hAllow ] := { => }
netiosrv[ _NETIOSRV_hBlock ] := { => }
netiosrv[ _NETIOSRV_mtxFilters ] := hb_mutexCreate()
netiosrv[ _NETIOSRV_cName ] := "Data"
netiosrv[ _NETIOSRV_nPort ] := _NETIOSRV_PORT_DEF
netiosrv[ _NETIOSRV_cIFAddr ] := _NETIOSRV_IPV4_DEF
netiosrv[ _NETIOSRV_cRootDir ] := hb_dirBase()
netiosrv[ _NETIOSRV_lRPC ] := .F.
netiosrv[ _NETIOSRV_lEncryption ] := .F.
netiosrv[ _NETIOSRV_lAcceptConn ] := .T.
netiosrv[ _NETIOSRV_lShowConn ] := .F.
netiosrv[ _NETIOSRV_lQuit ] := .F.
netiosrv[ _NETIOSRV_hConnection ] := { => }
netiosrv[ _NETIOSRV_mtxConnection ] := hb_mutexCreate()
netiosrv[ _NETIOSRV_hAllow ] := { => }
netiosrv[ _NETIOSRV_hBlock ] := { => }
netiosrv[ _NETIOSRV_mtxFilters ] := hb_mutexCreate()
hb_HKeepOrder( netiosrv[ _NETIOSRV_hConnection ], .T. )
hb_HKeepOrder( netiosrv[ _NETIOSRV_hAllow ], .T. )
hb_HKeepOrder( netiosrv[ _NETIOSRV_hBlock ], .T. )
netiomgm[ _NETIOSRV_cName ] := "Management"
netiomgm[ _NETIOSRV_nPort ] := _NETIOMGM_PORT_DEF
netiomgm[ _NETIOSRV_cIFAddr ] := _NETIOMGM_IPV4_DEF
netiomgm[ _NETIOSRV_lAcceptConn ] := .T.
netiomgm[ _NETIOSRV_lShowConn ] := .F.
netiomgm[ _NETIOSRV_hConnection ] := { => }
netiomgm[ _NETIOSRV_mtxConnection ] := hb_mutexCreate()
netiomgm[ _NETIOSRV_hAllow ] := { "127.0.0.1" => NIL, "::1" => NIL } /* only localhost can manage */
netiomgm[ _NETIOSRV_hBlock ] := { => }
netiomgm[ _NETIOSRV_mtxFilters ] := hb_mutexCreate()
netiomgm[ _NETIOSRV_cName ] := "Management"
netiomgm[ _NETIOSRV_nPort ] := _NETIOMGM_PORT_DEF
netiomgm[ _NETIOSRV_cIFAddr ] := _NETIOMGM_IPV4_DEF
netiomgm[ _NETIOSRV_lAcceptConn ] := .T.
netiomgm[ _NETIOSRV_lShowConn ] := .F.
netiomgm[ _NETIOSRV_hConnection ] := { => }
netiomgm[ _NETIOSRV_mtxConnection ] := hb_mutexCreate()
netiomgm[ _NETIOSRV_hAllow ] := { "127.0.0.1" => NIL, "::1" => NIL } /* only localhost can manage */
netiomgm[ _NETIOSRV_hBlock ] := { => }
netiomgm[ _NETIOSRV_mtxFilters ] := hb_mutexCreate()
netiomgm[ _NETIOSRV_hNotifStream ] := { => }
netiomgm[ _NETIOSRV_mtxNotifStream ] := hb_mutexCreate()
hb_HKeepOrder( netiomgm[ _NETIOSRV_hConnection ], .T. )
hb_HKeepOrder( netiomgm[ _NETIOSRV_hAllow ], .T. )
@@ -214,7 +214,7 @@ PROCEDURE Main( ... )
cPassword,;
NIL,;
NIL,;
{| pConnectionSocket | netiosrv_callback( netiosrv, pConnectionSocket, .F. ) } )
{| pConnectionSocket | netiosrv_callback( netiomgm, netiosrv, pConnectionSocket, .F. ) } )
netiosrv[ _NETIOSRV_lEncryption ] := ! Empty( cPassword )
cPassword := NIL
@@ -254,11 +254,11 @@ PROCEDURE Main( ... )
"hbnetiomgm_noconn" => {| ... | netiomgm_rpc_conn( netiosrv, .F. ) } ,;
"hbnetiomgm_logconn" => {| ... | netiomgm_rpc_logconn( netiosrv, .T. ) } ,;
"hbnetiomgm_nologconn" => {| ... | netiomgm_rpc_logconn( netiosrv, .F. ) } ,;
"hbnetiomgm_cargo" => {| ... | netiomgm_rpc_cargo( ... ) } },;
"hbnetiomgm_regnotif" => {| ... | netiomgm_rpc_regnotif( netiomgm, ... ) } },;
cPasswordManagement,;
NIL,;
NIL,;
{| pConnectionSocket | netiosrv_callback( netiomgm, pConnectionSocket, .T. ) } )
{| pConnectionSocket | netiosrv_callback( netiomgm, netiomgm, pConnectionSocket, .T. ) } )
IF Empty( netiomgm[ _NETIOSRV_pListenSocket ] )
OutStd( "Warning: Cannot start server management." + hb_eol() )
@@ -363,17 +363,16 @@ STATIC FUNCTION netiosrv_config( netiosrv, netiomgm )
#define _CLI_pConnSock 1
#define _CLI_nStreamID 2
#define _CLI_xCargo 3
#define _CLI_lNotify 4
#define _CLI_nSendErrors 5
#define _CLI_MAX_ 5
#define _CLI_lNotify 3
#define _CLI_nSendErrors 4
#define _CLI_MAX_ 4
STATIC PROCEDURE netiosrv_notifyclients( cMsg )
STATIC PROCEDURE netiosrv_notifyclients( netiomgm, cMsg )
LOCAL aClient
hb_mutexLock( s_mtxConnStream )
hb_mutexLock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
FOR EACH aClient IN s_hConnStream
FOR EACH aClient IN netiomgm[ _NETIOSRV_hNotifStream ]
IF aClient[ _CLI_lNotify ]
IF ! netio_srvSendItem( aClient[ _CLI_pConnSock ], aClient[ _CLI_nStreamID ], hb_TToS( hb_DateTime() ) + " " + cMsg )
++aClient[ _CLI_nSendErrors ]
@@ -381,13 +380,21 @@ STATIC PROCEDURE netiosrv_notifyclients( cMsg )
ENDIF
NEXT
hb_mutexUnLock( s_mtxConnStream )
/* Remove clients from notification list after certain amount of failures.
To handle clients that exited abnormally. */
FOR EACH aClient IN netiomgm[ _NETIOSRV_hNotifStream ] DESCEND
IF aClient[ _CLI_nSendErrors ] > 5
hb_HDel( netiomgm[ _NETIOSRV_hNotifStream ], aClient:__enumKey() )
ENDIF
NEXT
hb_mutexUnLock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
RETURN
/* Server connect callback */
STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
STATIC FUNCTION netiosrv_callback( netiomgm, netiosrv, pConnectionSocket, lManagement )
LOCAL aAddressPeer
LOCAL cAddressPeer
LOCAL cNamePeer
@@ -405,7 +412,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
hb_mutexLock( netiosrv[ _NETIOSRV_mtxFilters ] )
IF !( cAddressPeer $ netiosrv[ _NETIOSRV_hAllow ] )
IF hb_HScan( netiosrv[ _NETIOSRV_hAllow ], {| tmp | hb_WildMatch( tmp, cAddressPeer ) } ) == 0
cNamePeer := hb_socketGetPeerName( aAddressPeer ) /* TOFIX */
cNamePeer := NIL /* TOFIX: hb_socketResolveAddr( cAddressPeer ) */
IF cNamePeer == NIL
lBlocked := .T.
ELSE
@@ -421,7 +428,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxFilters ] )
IF lBlocked
IF ! lManagement
netiosrv_notifyclients( "Connection denied: " + cAddressPeer )
netiosrv_notifyclients( netiomgm, "Connection denied: " + cAddressPeer )
ENDIF
RETURN NIL
ENDIF
@@ -437,7 +444,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
lBlocked := .T.
ELSE
IF cNamePeer == NIL
cNamePeer := hb_socketGetPeerName( aAddressPeer ) /* TOFIX */
cNamePeer := NIL /* TOFIX: hb_socketResolveAddr( cAddressPeer ) */
ENDIF
IF cNamePeer != NIL
IF cNamePeer $ netiosrv[ _NETIOSRV_hBlock ]
@@ -453,7 +460,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxFilters ] )
IF lBlocked
IF ! lManagement
netiosrv_notifyclients( "Connection denied: " + cAddressPeer )
netiosrv_notifyclients( netiomgm, "Connection denied: " + cAddressPeer )
ENDIF
RETURN NIL
ENDIF
@@ -463,7 +470,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
QQOut( "Connecting (" + netiosrv[ _NETIOSRV_cName ] + "): " + cAddressPeer, hb_eol() )
ENDIF
IF ! lManagement
netiosrv_notifyclients( "Connecting: " + cAddressPeer )
netiosrv_notifyclients( netiomgm, "Connecting: " + cAddressPeer )
ENDIF
netiosrv_conn_register( netiosrv, pConnectionSocket )
@@ -479,7 +486,7 @@ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket, lManagement )
QQOut( "Disconnected (" + netiosrv[ _NETIOSRV_cName ] + "): " + AddrToIPPort( aAddressPeer ), hb_eol() )
ENDIF
IF ! lManagement
netiosrv_notifyclients( "Diconnected: " + cAddressPeer )
netiosrv_notifyclients( netiomgm, "Diconnected: " + cAddressPeer )
ENDIF
ENDIF
@@ -517,31 +524,32 @@ STATIC PROCEDURE netiosrv_conn_unregister( netiosrv, pConnectionSocket )
/* RPC management interface */
STATIC FUNCTION netiomgm_rpc_cargo( pConnSock, nStreamID, xCargo )
STATIC FUNCTION netiomgm_rpc_regnotif( netiomgm, pConnSock, nStreamID, lRegister )
LOCAL index := hb_valToStr( pConnSock )
LOCAL cli
SWITCH PCount()
CASE 1
RETURN iif( index $ s_hConnStream, s_hConnStream[ index ][ _CLI_xCargo ], NIL )
CASE 3
IF xCargo == NIL
hb_mutexLock( s_mtxConnStream )
IF index $ s_hConnStream
hb_HDel( s_hConnStream, index )
#if 0
CASE 2
RETURN iif( index $ netiomgm[ _NETIOSRV_hNotifStream ], netiomgm[ _NETIOSRV_hNotifStream ][ index ][ _CLI_xCargo ], NIL )
#endif
CASE 4
IF ! hb_isLogical( lRegister ) .OR. ! lRegister
hb_mutexLock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
IF index $ netiomgm[ _NETIOSRV_hNotifStream ]
hb_HDel( netiomgm[ _NETIOSRV_hNotifStream ], index )
ENDIF
hb_mutexUnlock( s_mtxConnStream )
hb_mutexUnlock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
RETURN -1
ELSE
cli := Array( _CLI_MAX_ )
cli[ _CLI_pConnSock ] := pConnSock
cli[ _CLI_nStreamID ] := nStreamID
cli[ _CLI_xCargo ] := xCargo
cli[ _CLI_lNotify ] := .T.
cli[ _CLI_nSendErrors ] := 0
hb_mutexLock( s_mtxConnStream )
s_hConnStream[ index ] := cli
hb_mutexUnlock( s_mtxConnStream )
hb_mutexLock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
netiomgm[ _NETIOSRV_hNotifStream ][ index ] := cli
hb_mutexUnlock( netiomgm[ _NETIOSRV_mtxNotifStream ] )
RETURN nStreamID
ENDIF
ENDSWITCH
@@ -643,7 +651,6 @@ STATIC FUNCTION netiomgm_rpc_clientinfo( netiosrv, netiomgm, cIPPort )
netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_PEERADDRESS, @aAddressPeer )
IF cIPPort == AddrToIPPort( aAddressPeer )
// xCargo := netiomgm_rpc_cargo( nconn[ _NETIOSRV_CONN_pConnection ] )
xCargo := nconn[ _NETIOSRV_CONN_hInfo ]
lDone := .T.
EXIT
@@ -660,7 +667,6 @@ STATIC FUNCTION netiomgm_rpc_clientinfo( netiosrv, netiomgm, cIPPort )
netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_PEERADDRESS, @aAddressPeer )
IF cIPPort == AddrToIPPort( aAddressPeer )
// xCargo := netiomgm_rpc_cargo( nconn[ _NETIOSRV_CONN_pConnection ] )
xCargo := nconn[ _NETIOSRV_CONN_hInfo ]
EXIT
ENDIF
@@ -713,7 +719,7 @@ STATIC FUNCTION netiomgm_rpc_conninfo( netiosrv )
"nBytesSent" => nBytesSent,;
"nBytesReceived" => nBytesReceived,;
"cAddressPeer" => AddrToIPPort( aAddressPeer ),;
"xCargo" => netiomgm_rpc_cargo( nconn[ _NETIOSRV_CONN_pConnection ] ) } )
"xCargo" => nconn[ _NETIOSRV_CONN_hInfo ] } )
NEXT
hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxConnection ] )
@@ -793,6 +799,19 @@ STATIC FUNCTION AddrToIPPort( aAddr )
RETURN cIP
STATIC FUNCTION AddrToIP( aAddr )
LOCAL cIP
IF hb_isArray( aAddr ) .AND. ;
( aAddr[ HB_SOCKET_ADINFO_FAMILY ] == HB_SOCKET_AF_INET .OR. ;
aAddr[ HB_SOCKET_ADINFO_FAMILY ] == HB_SOCKET_AF_INET6 )
cIP := aAddr[ HB_SOCKET_ADINFO_ADDRESS ]
ELSE
cIP := ""
ENDIF
RETURN cIP
/* Helper functions */
STATIC FUNCTION FileSig( cFile )