From adfd4ba1752137ebc74c3b3ab8a267a32a27a82d Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Wed, 26 Jan 2011 01:11:04 +0000 Subject: [PATCH] 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. --- harbour/ChangeLog | 12 + .../hbnetio/utils/netiosrv/netiocmd.prg | 224 ++++++++++++-- .../hbnetio/utils/netiosrv/netiosrv.prg | 287 ++++++------------ 3 files changed, 297 insertions(+), 226 deletions(-) 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 " )