diff --git a/harbour/ChangeLog b/harbour/ChangeLog index cbb984ccf4..a902e69d1e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,18 @@ The license applies to all entries newer than 2009-04-28. */ +2011-01-26 02:10 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbnetio/utils/netiosrv/netiosrv.prg + * contrib/hbnetio/utils/netiosrv/netiocmd.prg + + Console UI moved to separate thread and it's now fully + contained in netiocmd.prg. The only communication between + console UI and netio server is via remote management RPC + interface. + This means the console UI can be easily removed or moved + to separate executable. + + Added -noui cmdline option which disables interactive console. + ; Little rough around the edges, but it show the capabilities. + 2011-01-25 14:41 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com) * contrib/hbnetio/utils/netiosrq/netiosrq.hbp % Fix to previous partial fix. diff --git a/harbour/contrib/hbnetio/utils/netiosrv/netiocmd.prg b/harbour/contrib/hbnetio/utils/netiosrv/netiocmd.prg index 9de38a5be6..d0bdb39bd8 100644 --- a/harbour/contrib/hbnetio/utils/netiosrv/netiocmd.prg +++ b/harbour/contrib/hbnetio/utils/netiosrv/netiocmd.prg @@ -12,37 +12,28 @@ * */ -FUNCTION hbnetiosrv_LoadCmds( bQuit, bShowInfo ) +#include "color.ch" +#include "inkey.ch" +#include "setcurs.ch" + +#include "hbgtinfo.ch" + +STATIC FUNCTION hbnetiosrv_LoadCmds() LOCAL hCmds := { ; - "?" => { "" , "Synonym for 'help'." , {|| cmdHelp( hCmds ) } },; - "clear" => { "" , "Clear screen." , {|| Scroll(), SetPos( 0, 0 ) } },; - "config" => { "" , "Show server configuration." , bShowInfo },; - "sysinfo" => { "" , "Show system/build information." , {|| cmdSysInfo() } },; - "show" => { "" , "Show list of connections." , {| cCommand, netiosrv | HB_SYMBOL_UNUSED( cCommand ), cmdConnInfo( netiosrv ) } },; - "noconn" => { "" , "Disable incoming connections." , {| cCommand, netiosrv | HB_SYMBOL_UNUSED( cCommand ), cmdConnEnable( netiosrv, .F. ) } },; - "conn" => { "" , "Enable incoming connections." , {| cCommand, netiosrv | HB_SYMBOL_UNUSED( cCommand ), cmdConnEnable( netiosrv, .T. ) } },; - "noshconn" => { "" , "Disable showing incoming connections." , {| cCommand, netiosrv | HB_SYMBOL_UNUSED( cCommand ), cmdConnShowEnable( netiosrv, .F. ) } },; - "shconn" => { "" , "Enable showing incoming connections." , {| cCommand, netiosrv | HB_SYMBOL_UNUSED( cCommand ), cmdConnShowEnable( netiosrv, .T. ) } },; - "stop" => { "[|all]", "Stop specified connection(s)." , {| cCommand, netiosrv | cmdConnStop( cCommand, netiosrv ) } },; - "quit" => { "" , "Stop server and exit." , bQuit },; - "help" => { "" , "Display this help." , {|| cmdHelp( hCmds ) } }; - } + "?" => { "" , "Synonym for 'help'." , {|| cmdHelp( hCmds ) } },; + "clear" => { "" , "Clear screen." , {|| Scroll(), SetPos( 0, 0 ) } },; + "sysinfo" => { "" , "Show system/build information." , {|| cmdSysInfo() } },; + "show" => { "" , "Show list of connections." , {|| cmdConnInfo() } },; + "noconn" => { "" , "Disable incoming connections." , {|| cmdConnEnable( .F. ) } },; + "conn" => { "" , "Enable incoming connections." , {|| cmdConnEnable( .T. ) } },; + "nologconn" => { "" , "Disable logging incoming connections." , {|| cmdConnLogEnable( .F. ) } },; + "logconn" => { "" , "Enable logging incoming connections." , {|| cmdConnLogEnable( .T. ) } },; + "stop" => { "[|all]", "Stop specified connection(s)." , {| cCommand | cmdConnStop( cCommand ) } },; + "quit" => { "" , "Stop server and exit." , {|| netio_funcexec( "netio_shutdown" ) } },; + "help" => { "" , "Display this help." , {|| cmdHelp( hCmds ) } } } RETURN hCmds -/* TODO: - on the fly change of RPC filter modules - - listing open files - - listing active locks - - gracefully shutting down server by waiting for connections to close and not accept new ones - - pausing server */ - -STATIC PROCEDURE cmdSysInfo() - QQOut( "OS: " + OS(), hb_eol() ) - QQOut( "Harbour: " + Version(), hb_eol() ) - QQOut( "C Compiler: " + hb_Compiler(), hb_eol() ) - QQOut( "Memory: " + hb_ntos( Memory( 0 ) ) + "KB", hb_eol() ) - RETURN - STATIC PROCEDURE cmdHelp( hCommands ) LOCAL aTexts := {} LOCAL n, c, m @@ -83,3 +74,182 @@ STATIC PROCEDURE cmdHelp( hCommands ) NEXT RETURN + +PROCEDURE netio_cmdUI( cIP, nPort, cPassword ) + LOCAL GetList := {} + LOCAL hCommands + LOCAL nSavedRow + LOCAL nPos + LOCAL aCommand + LOCAL cCommand + + LOCAL bKeyDown + LOCAL bKeyUp + LOCAL bKeyIns + LOCAL bKeyPaste + LOCAL bKeyTab + + LOCAL aHistory, nHistIndex + + LOCAL lOk + + /* connect to the server */ + QQOut( "Connecting to server management interface...", hb_eol() ) + + lOk := netio_connect( cIP, nPort,, cPassword ) + cPassword := NIL + + IF lOk + + QQOut( "Connected.", hb_eol() ) + QQOut( hb_eol() ) + QQOut( "Type a command or '?' for help.", hb_eol() ) + + aHistory := { "quit" } + nHistIndex := Len( aHistory ) + 1 + hCommands := hbnetiosrv_LoadCmds() + + /* Command prompt */ + DO WHILE .T. + + cCommand := Space( 128 ) + + QQOut( "hbnetiosrv$ " ) + nSavedRow := Row() + + @ nSavedRow, Col() GET cCommand PICTURE "@S" + hb_ntos( MaxCol() - Col() + 1 ) COLOR hb_ColorIndex( SetColor(), CLR_STANDARD ) + "," + hb_ColorIndex( SetColor(), CLR_STANDARD ) + + SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) ) + + bKeyIns := SetKey( K_INS,; + {|| SetCursor( iif( ReadInsert( ! ReadInsert() ),; + SC_NORMAL, SC_INSERT ) ) } ) + bKeyUp := SetKey( K_UP,; + {|| iif( nHistIndex > 1,; + cCommand := PadR( aHistory[ --nHistIndex ], Len( cCommand ) ), ),; + ManageCursor( cCommand ) } ) + bKeyDown := SetKey( K_DOWN,; + {|| cCommand := PadR( iif( nHistIndex < Len( aHistory ),; + aHistory[ ++nHistIndex ],; + ( nHistIndex := Len( aHistory ) + 1, "" ) ), Len( cCommand ) ),; + ManageCursor( cCommand ) } ) + bKeyPaste := SetKey( K_ALT_V, {|| hb_gtInfo( HB_GTI_CLIPBOARDPASTE )}) + + bKeyTab := SetKey( K_TAB, {|| CompleteCmd( @cCommand, hCommands ) } ) + + READ + + /* Positions the cursor on the line previously saved */ + SetPos( nSavedRow, MaxCol() - 1 ) + + SetKey( K_ALT_V, bKeyPaste ) + SetKey( K_DOWN, bKeyDown ) + SetKey( K_UP, bKeyUp ) + SetKey( K_INS, bKeyIns ) + SetKey( K_TAB, bKeyTab ) + + QQOut( hb_eol() ) + + cCommand := AllTrim( cCommand ) + + IF Empty( cCommand ) + LOOP + ENDIF + + IF Empty( aHistory ) .OR. ! ATail( aHistory ) == cCommand + IF Len( aHistory ) < 64 + AAdd( aHistory, cCommand ) + ELSE + ADel( aHistory, 1 ) + aHistory[ Len( aHistory ) ] := cCommand + ENDIF + ENDIF + nHistIndex := Len( aHistory ) + 1 + + aCommand := hb_ATokens( cCommand, " " ) + IF ! Empty( aCommand ) .AND. ( nPos := hb_HPos( hCommands, Lower( aCommand[ 1 ] ) ) ) > 0 + Eval( hb_HValueAt( hCommands, nPos )[ 3 ], cCommand ) + ELSE + QQOut( "Error: Unknown command '" + cCommand + "'.", hb_eol() ) + ENDIF + ENDDO + + /* Never reached */ + netio_disconnect( cIP, nPort ) + ENDIF + + RETURN + +/* Adjusted the positioning of cursor on navigate through history. [vailtom] */ +STATIC PROCEDURE ManageCursor( cCommand ) + KEYBOARD Chr( K_HOME ) + iif( ! Empty( cCommand ), Chr( K_END ), "" ) + RETURN + +/* Complete the command line, based on the first characters that the user typed. [vailtom] */ +STATIC PROCEDURE CompleteCmd( cCommand, hCommands ) + LOCAL s := Lower( AllTrim( cCommand ) ) + LOCAL n + + /* We need at least one character to search */ + IF Len( s ) > 1 + FOR EACH n IN hCommands + IF s == Lower( Left( n:__enumKey(), Len( s ) ) ) + cCommand := PadR( n:__enumKey(), Len( cCommand ) ) + ManageCursor( cCommand ) + RETURN + ENDIF + NEXT + ENDIF + RETURN + +/* Commands */ + +STATIC PROCEDURE cmdSysInfo() + LOCAL cLine + + FOR EACH cLine IN netio_funcexec( "netio_sysinfo" ) + QQOut( cLine, hb_eol() ) + NEXT + + RETURN + +STATIC PROCEDURE cmdConnStop( cCommand ) + LOCAL aToken := hb_ATokens( cCommand, " " ) + + IF Len( aToken ) > 1 + netio_funcexec( "netio_stop", aToken[ 2 ] ) + ELSE + QQOut( "Error: Invalid syntax.", hb_eol() ) + ENDIF + + RETURN + +STATIC PROCEDURE cmdConnInfo() + LOCAL aArray := netio_funcexec( "netio_conninfo" ) + LOCAL hConn + + QQOut( "Number of connections: " + hb_ntos( Len( aArray ) ), hb_eol() ) + + FOR EACH hConn IN aArray + QQOut( "#" + hb_ntos( hConn:__enumIndex() ) + " " +; + hb_TToC( hConn[ "tStart" ], "YYYY.MM.DD", "HH:MM:SS" ) + " " +; + PadR( hConn[ "cStatus" ], 12 ) + " " +; + "fcnt: " + Str( hConn[ "nFilesCount" ] ) + " " +; + "send: " + Str( hConn[ "nBytesSent" ] ) + " " +; + "recv: " + Str( hConn[ "nBytesReceived" ] ) + " " +; + hConn[ "cAddressPeer" ], hb_eol() ) + NEXT + + RETURN + +PROCEDURE cmdConnEnable( lValue ) + + netio_funcexec( "netio_conn", lValue ) + + RETURN + +PROCEDURE cmdConnLogEnable( lValue ) + + netio_funcexec( "netio_logconn", lValue ) + + RETURN diff --git a/harbour/contrib/hbnetio/utils/netiosrv/netiosrv.prg b/harbour/contrib/hbnetio/utils/netiosrv/netiosrv.prg index 5d0b9b1aaa..04ec540cec 100644 --- a/harbour/contrib/hbnetio/utils/netiosrv/netiosrv.prg +++ b/harbour/contrib/hbnetio/utils/netiosrv/netiosrv.prg @@ -13,17 +13,20 @@ * */ -#include "color.ch" +/* TODO: - on the fly change of RPC filter modules + - listing open files + - listing active locks + - gracefully shutting down server by waiting for connections to close and not accept new ones + - pausing server + - sort out console UI from server side log output */ + #include "fileio.ch" -#include "inkey.ch" -#include "setcurs.ch" -#include "hbnetio.ch" - -#include "hbgtinfo.ch" #include "hbhrb.ch" #include "hbsocket.ch" +#include "hbnetio.ch" + /* netio_mtserver() needs MT HVM version */ REQUEST HB_MT @@ -44,10 +47,11 @@ REQUEST HB_MT #define _NETIOSRV_lEncryption 8 #define _NETIOSRV_lAcceptConn 9 #define _NETIOSRV_lShowConn 10 -#define _NETIOSRV_pListenSocket 11 -#define _NETIOSRV_hConnection 12 -#define _NETIOSRV_mtxConnection 13 -#define _NETIOSRV_MAX_ 13 +#define _NETIOSRV_lQuit 11 +#define _NETIOSRV_pListenSocket 12 +#define _NETIOSRV_hConnection 13 +#define _NETIOSRV_mtxConnection 14 +#define _NETIOSRV_MAX_ 14 #define _NETIOSRV_CONN_pConnection 1 #define _NETIOSRV_CONN_tStart 2 @@ -58,27 +62,13 @@ PROCEDURE Main( ... ) LOCAL netiomgm[ _NETIOSRV_MAX_ ] LOCAL cParam - LOCAL aCommand - LOCAL cCommand LOCAL cPassword LOCAL cPasswordManagement - LOCAL bKeyDown - LOCAL bKeyUp - LOCAL bKeyIns - LOCAL bKeyPaste - LOCAL bKeyTab - - LOCAL GetList := {} - LOCAL lQuit - LOCAL hCommands - LOCAL nSavedRow - LOCAL nPos - LOCAL cExt LOCAL cFile - LOCAL aHistory, nHistIndex + LOCAL lUI := .T. SET DATE ANSI SET CENTURY ON @@ -93,6 +83,7 @@ PROCEDURE Main( ... ) netiosrv[ _NETIOSRV_lEncryption ] := .F. netiosrv[ _NETIOSRV_lAcceptConn ] := .T. netiosrv[ _NETIOSRV_lShowConn ] := .F. + netiosrv[ _NETIOSRV_lQuit ] := .F. netiosrv[ _NETIOSRV_hConnection ] := { => } netiosrv[ _NETIOSRV_mtxConnection ] := hb_mutexCreate() @@ -102,7 +93,7 @@ PROCEDURE Main( ... ) netiomgm[ _NETIOSRV_nPort ] := 2940 netiomgm[ _NETIOSRV_cIFAddr ] := "127.0.0.1" netiomgm[ _NETIOSRV_lAcceptConn ] := .T. - netiomgm[ _NETIOSRV_lShowConn ] := .T. + netiomgm[ _NETIOSRV_lShowConn ] := .F. netiomgm[ _NETIOSRV_hConnection ] := { => } netiomgm[ _NETIOSRV_mtxConnection ] := hb_mutexCreate() @@ -110,6 +101,8 @@ PROCEDURE Main( ... ) FOR EACH cParam IN { ... } DO CASE + CASE Lower( Left( cParam, 5 ) ) == "-noui" + lUI := .F. CASE Lower( Left( cParam, 6 ) ) == "-port=" netiosrv[ _NETIOSRV_nPort ] := Val( SubStr( cParam, 7 ) ) CASE Lower( Left( cParam, 7 ) ) == "-iface=" @@ -193,93 +186,37 @@ PROCEDURE Main( ... ) netio_mtserver( netiomgm[ _NETIOSRV_nPort ],; netiomgm[ _NETIOSRV_cIFAddr ],; NIL,; - { "netio_shutdown" => {|| netio_shutdown( @lQuit ) } ,; - "netio_conninfo" => {|| netio_conninfo( netiosrv ) } },; + { "netio_sysinfo" => {| ... | netio_mgmt_rpc_sysinfo() } ,; + "netio_shutdown" => {| ... | netio_mgmt_rpc_shutdown( netiosrv ) } ,; + "netio_conninfo" => {| ... | netio_mgmt_rpc_conninfo( netiosrv ) } ,; + "netio_stop" => {| ... | netio_mgmt_rpc_stop( netiosrv, ... ) } ,; + "netio_conn" => {| ... | netio_mgmt_rpc_conn( netiosrv, .T. ) } ,; + "netio_noconn" => {| ... | netio_mgmt_rpc_conn( netiosrv, .F. ) } ,; + "netio_logconn" => {| ... | netio_mgmt_rpc_logconn( netiosrv, .T. ) } ,; + "netio_nologconn" => {| ... | netio_mgmt_rpc_logconn( netiosrv, .F. ) } },; cPasswordManagement,; NIL,; NIL,; {| pConnectionSocket | netiosrv_callback( netiomgm, pConnectionSocket ) } ) - cPasswordManagement := NIL IF Empty( netiomgm[ _NETIOSRV_pListenSocket ] ) OutStd( "Warning: Cannot start server management." + hb_eol() ) + ELSE + IF lUI + hb_threadDetach( hb_threadStart( {|| netio_cmdUI( netiomgm[ _NETIOSRV_cIFAddr ], netiomgm[ _NETIOSRV_nPort ], cPasswordManagement ) } ) ) + ENDIF ENDIF ENDIF ShowConfig( netiosrv, netiomgm ) - OutStd( hb_eol() ) - OutStd( "Type a command or '?' for help.", hb_eol() ) + hb_idleSleep( 2 ) - lQuit := .F. - aHistory := { "quit" } - nHistIndex := Len( aHistory ) + 1 - hCommands := hbnetiosrv_LoadCmds( {|| lQuit := .T. },; /* codeblock to quit */ - {|| ShowConfig( netiosrv ) } ) /* codeblock to display config both uses local vars */ + netiomgm[ _NETIOSRV_lShowConn ] := .T. /* Command prompt */ - DO WHILE ! lQuit - - cCommand := Space( 128 ) - - QQOut( "hbnetiosrv$ " ) - nSavedRow := Row() - - @ nSavedRow, Col() GET cCommand PICTURE "@S" + hb_ntos( MaxCol() - Col() + 1 ) COLOR hb_ColorIndex( SetColor(), CLR_STANDARD ) + "," + hb_ColorIndex( SetColor(), CLR_STANDARD ) - - SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) ) - - bKeyIns := SetKey( K_INS,; - {|| SetCursor( iif( ReadInsert( ! ReadInsert() ),; - SC_NORMAL, SC_INSERT ) ) } ) - bKeyUp := SetKey( K_UP,; - {|| iif( nHistIndex > 1,; - cCommand := PadR( aHistory[ --nHistIndex ], Len( cCommand ) ), ),; - ManageCursor( cCommand ) } ) - bKeyDown := SetKey( K_DOWN,; - {|| cCommand := PadR( iif( nHistIndex < Len( aHistory ),; - aHistory[ ++nHistIndex ],; - ( nHistIndex := Len( aHistory ) + 1, "" ) ), Len( cCommand ) ),; - ManageCursor( cCommand ) } ) - bKeyPaste := SetKey( K_ALT_V, {|| hb_gtInfo( HB_GTI_CLIPBOARDPASTE )}) - - bKeyTab := SetKey( K_TAB, {|| CompleteCmd( @cCommand, hCommands ) } ) - - READ - - /* Positions the cursor on the line previously saved */ - SetPos( nSavedRow, MaxCol() - 1 ) - - SetKey( K_ALT_V, bKeyPaste ) - SetKey( K_DOWN, bKeyDown ) - SetKey( K_UP, bKeyUp ) - SetKey( K_INS, bKeyIns ) - SetKey( K_TAB, bKeyTab ) - - QQOut( hb_eol() ) - - cCommand := AllTrim( cCommand ) - - IF Empty( cCommand ) - LOOP - ENDIF - - IF Empty( aHistory ) .OR. ! ATail( aHistory ) == cCommand - IF Len( aHistory ) < 64 - AAdd( aHistory, cCommand ) - ELSE - ADel( aHistory, 1 ) - aHistory[ Len( aHistory ) ] := cCommand - ENDIF - ENDIF - nHistIndex := Len( aHistory ) + 1 - - aCommand := hb_ATokens( cCommand, " " ) - IF ! Empty( aCommand ) .AND. ( nPos := hb_HPos( hCommands, Lower( aCommand[ 1 ] ) ) ) > 0 - Eval( hb_HValueAt( hCommands, nPos )[ 3 ], cCommand, netiosrv ) - ELSE - QQOut( "Error: Unknown command '" + cCommand + "'.", hb_eol() ) - ENDIF + DO WHILE ! netiosrv[ _NETIOSRV_lQuit ] + hb_idleSleep( 5 ) ENDDO netio_serverstop( netiosrv[ _NETIOSRV_pListenSocket ] ) @@ -296,54 +233,7 @@ PROCEDURE Main( ... ) RETURN -STATIC FUNCTION netio_shutdown( /* @ */ lQuit ) - - QQOut( "Shutdown initiated...", hb_eol() ) - - lQuit := .T. - - hb_keyPut( { K_HOME, K_CTRL_Y, K_ENTER } ) - - RETURN .T. - -STATIC FUNCTION netio_conninfo( netiosrv ) - LOCAL nconn - - LOCAL nStatus - LOCAL nFilesCount - LOCAL nBytesSent - LOCAL nBytesReceived - LOCAL aAddressPeer - - LOCAL aArray := {} - - hb_mutexLock( netiosrv[ _NETIOSRV_mtxConnection ] ) - - FOR EACH nconn IN netiosrv[ _NETIOSRV_hConnection ] - - nFilesCount := 0 - nBytesSent := 0 - nBytesReceived := 0 - aAddressPeer := NIL - - nStatus := ; - netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_FILESCOUNT , @nFilesCount ) - netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_BYTESSENT , @nBytesSent ) - netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_BYTESRECEIVED, @nBytesReceived ) - netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_PEERADDRESS , @aAddressPeer ) - - AAdd( aArray, {; - "tStart" => nconn[ _NETIOSRV_CONN_tStart ],; - "cStatus" => ConnStatusStr( nStatus ),; - "nFilesCount" => nFilesCount,; - "nBytescount" => nBytesSent,; - "nBytesreceived" => nBytesReceived,; - "cAddressPeer" => AddrToIPPort( aAddressPeer ) } ) - NEXT - - hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxConnection ] ) - - RETURN aArray +/* Server connect callback */ STATIC FUNCTION netiosrv_callback( netiosrv, pConnectionSocket ) LOCAL aAddressPeer @@ -400,28 +290,40 @@ STATIC PROCEDURE netiosrv_conn_unregister( netiosrv, pConnectionSocket ) RETURN -PROCEDURE cmdConnEnable( netiosrv, lValue ) +/* RPC management interface */ - netiosrv[ _NETIOSRV_lAcceptConn ] := lValue +STATIC FUNCTION netio_mgmt_rpc_sysinfo() + RETURN {; + "OS: " + OS() ,; + "Harbour: " + Version() ,; + "C Compiler: " + hb_Compiler() ,; + "Memory (KB): " + hb_ntos( Memory( 0 ) ) } - RETURN +STATIC FUNCTION netio_mgmt_rpc_logconn( netiosrv, lValue ) + LOCAL lOldValue := netiosrv[ _NETIOSRV_lAcceptConn ] -PROCEDURE cmdConnShowEnable( netiosrv, lValue ) + IF hb_isLogical( lValue ) + netiosrv[ _NETIOSRV_lShowConn ] := lValue + ENDIF - netiosrv[ _NETIOSRV_lShowConn ] := lValue + RETURN lOldValue - RETURN +STATIC FUNCTION netio_mgmt_rpc_conn( netiosrv, lValue ) + LOCAL lOldValue := netiosrv[ _NETIOSRV_lAcceptConn ] -PROCEDURE cmdConnStop( cCommand, netiosrv ) - LOCAL aToken := hb_ATokens( cCommand, " " ) + IF hb_isLogical( lValue ) + netiosrv[ _NETIOSRV_lAcceptConn ] := lValue + ENDIF - LOCAL aAddressPeer - LOCAL cIPPort + RETURN lOldValue + +STATIC FUNCTION netio_mgmt_rpc_stop( netiosrv, cIPPort ) LOCAL nconn + LOCAL aAddressPeer - IF Len( aToken ) > 1 + IF hb_isString( cIPPort ) - cIPPort := Lower( aToken[ 2 ] ) + cIPPort := Lower( cIPPort ) hb_mutexLock( netiosrv[ _NETIOSRV_mtxConnection ] ) @@ -437,13 +339,21 @@ PROCEDURE cmdConnStop( cCommand, netiosrv ) NEXT hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxConnection ] ) - ELSE - QQOut( "Error: Invalid syntax.", hb_eol() ) + + RETURN .T. ENDIF - RETURN + RETURN .F. -PROCEDURE cmdConnInfo( netiosrv ) +STATIC FUNCTION netio_mgmt_rpc_shutdown( netiosrv ) + + QQOut( "Shutdown initiated...", hb_eol() ) + + netiosrv[ _NETIOSRV_lQuit ] := .T. + + RETURN .T. + +STATIC FUNCTION netio_mgmt_rpc_conninfo( netiosrv ) LOCAL nconn LOCAL nStatus @@ -452,9 +362,9 @@ PROCEDURE cmdConnInfo( netiosrv ) LOCAL nBytesReceived LOCAL aAddressPeer - hb_mutexLock( netiosrv[ _NETIOSRV_mtxConnection ] ) + LOCAL aArray := {} - QQOut( "Number of connections: " + hb_ntos( Len( netiosrv[ _NETIOSRV_hConnection ] ) ), hb_eol() ) + hb_mutexLock( netiosrv[ _NETIOSRV_mtxConnection ] ) FOR EACH nconn IN netiosrv[ _NETIOSRV_hConnection ] @@ -469,18 +379,18 @@ PROCEDURE cmdConnInfo( netiosrv ) netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_BYTESRECEIVED, @nBytesReceived ) netio_srvStatus( nconn[ _NETIOSRV_CONN_pConnection ], NETIO_SRVINFO_PEERADDRESS , @aAddressPeer ) - QQOut( "#" + hb_ntos( nconn:__enumIndex() ) + " " +; - hb_TToC( nconn[ _NETIOSRV_CONN_tStart ], "YYYY.MM.DD", "HH:MM:SS" ) + " " +; - PadR( ConnStatusStr( nStatus ), 12 ) + " " +; - "fcnt: " + Str( nFilesCount ) + " " +; - "send: " + Str( nBytesSent ) + " " +; - "recv: " + Str( nBytesReceived ) + " " +; - AddrToIPPort( aAddressPeer ), hb_eol() ) + AAdd( aArray, {; + "tStart" => nconn[ _NETIOSRV_CONN_tStart ],; + "cStatus" => ConnStatusStr( nStatus ),; + "nFilesCount" => nFilesCount,; + "nBytesSent" => nBytesSent,; + "nBytesReceived" => nBytesReceived,; + "cAddressPeer" => AddrToIPPort( aAddressPeer ) } ) NEXT hb_mutexUnlock( netiosrv[ _NETIOSRV_mtxConnection ] ) - RETURN + RETURN aArray STATIC FUNCTION ConnStatusStr( nStatus ) @@ -508,6 +418,8 @@ STATIC FUNCTION AddrToIPPort( aAddr ) RETURN cIP +/* Helper functions */ + STATIC FUNCTION FileSig( cFile ) LOCAL hFile LOCAL cBuff, cSig, cExt @@ -526,28 +438,6 @@ STATIC FUNCTION FileSig( cFile ) RETURN cExt -/* Complete the command line, based on the first characters that the user typed. [vailtom] */ -STATIC PROCEDURE CompleteCmd( cCommand, hCommands ) - LOCAL s := Lower( AllTrim( cCommand ) ) - LOCAL n - - /* We need at least one character to search */ - IF Len( s ) > 1 - FOR EACH n IN hCommands - IF s == Lower( Left( n:__enumKey(), Len( s ) ) ) - cCommand := PadR( n:__enumKey(), Len( cCommand ) ) - ManageCursor( cCommand ) - RETURN - ENDIF - NEXT - ENDIF - RETURN - -/* Adjusted the positioning of cursor on navigate through history. [vailtom] */ -STATIC PROCEDURE ManageCursor( cCommand ) - KEYBOARD Chr( K_HOME ) + iif( ! Empty( cCommand ), Chr( K_END ), "" ) - RETURN - STATIC PROCEDURE ShowConfig( netiosrv, netiomgm ) QQOut( "Listening on: " + netiosrv[ _NETIOSRV_cIFAddr ] + ":" + hb_ntos( netiosrv[ _NETIOSRV_nPort ] ), hb_eol() ) @@ -563,8 +453,8 @@ STATIC PROCEDURE ShowConfig( netiosrv, netiomgm ) STATIC PROCEDURE HB_Logo() - OutStd( "Harbour NETIO Server " + HBRawVersion() + hb_eol() +; - "Copyright (c) 2009-2011, Przemyslaw Czerpak" + hb_eol() + ; + OutStd( "Harbour NETIO Server " + StrTran( Version(), "Harbour " ) + hb_eol() +; + "Copyright (c) 2009-2011, Przemyslaw Czerpak, Viktor Szakats" + hb_eol() + ; "http://harbour-project.org/" + hb_eol() +; hb_eol() ) @@ -587,6 +477,8 @@ STATIC PROCEDURE HB_Usage() OutStd( hb_StrFormat( " '%1$s()'", _RPC_FILTER ) , hb_eol() ) OutStd( " -pass= set server password" , hb_eol() ) OutStd( hb_eol() ) + OutStd( " -noui don't open interactive console" , hb_eol() ) + OutStd( hb_eol() ) OutStd( " -adminport= accept management connections on IP port " , hb_eol() ) OutStd( " -adminiface= accept manegement connections on IPv4 interface " , hb_eol() ) OutStd( " -adminpass= set remote management password" , hb_eol() ) @@ -595,6 +487,3 @@ STATIC PROCEDURE HB_Usage() OutStd( " -help|--help this help" , hb_eol() ) RETURN - -STATIC FUNCTION HBRawVersion() - RETURN StrTran( Version(), "Harbour " )