diff --git a/ftk/Makefile b/ftk/Makefile index 93055c6..b740b0f 100644 --- a/ftk/Makefile +++ b/ftk/Makefile @@ -207,6 +207,7 @@ submake_targets = netware_ring_0_target = sparc_generic = debian_arch = unknown +with_openssl = # -- Enable command echoing -- @@ -607,6 +608,11 @@ ifneq (,$(findstring sparcgeneric,$(MAKECMDGOALS))) sparc_generic = yes endif +ifneq (,$(findstring openssl,$(MAKECMDGOALS))) + submake_targets += openssl + with_openssl = yes +endif + # -- Helper functions -- define normpath @@ -873,8 +879,7 @@ ifdef win_target # Libraries that our various components need to link against - lib_link_libs = imagehlp.lib user32.lib rpcrt4.lib wsock32.lib advapi32.lib - exe_link_libs = $(lib_link_libs) + link_libs = imagehlp.lib user32.lib rpcrt4.lib wsock32.lib advapi32.lib # Convert the list of defines into a proper set of command-line params @@ -1067,6 +1072,12 @@ ifdef unix_target ccdefs += FLM_DEBUG ccflags += -g endif + + # Use OpenSSL + + ifdef with_openssl + ccdefs += FLM_OPENSSL + endif # Convert the list of defines into a proper set of command-line params @@ -1095,12 +1106,14 @@ ifdef unix_target endif endif - lib_link_libs = -lpthread - exe_link_libs = -lpthread + link_libs = -lpthread ifeq ($(target_os_family),linux) - lib_link_libs += -lrt -lstdc++ -ldl -lncurses - exe_link_libs += -lrt -lstdc++ -ldl -lncurses + link_libs += -lrt -lstdc++ -ldl -lncurses + ifdef with_openssl + link_libs += -lssl -lcrypto -ldl -lz + endif + shared_link_flags += -shared -Wl,-Bsymbolic -fpic \ -Wl,-soname,$(@F) -o $@ endif @@ -1118,8 +1131,7 @@ ifdef unix_target endif endif - lib_link_libs += -lm -lc -ldl -lsocket -lnsl -lrt -lcurses - exe_link_libs += -lm -lc -ldl -lsocket -lnsl -lrt -lcurses + link_libs += -lm -lc -ldl -lsocket -lnsl -lrt -lcurses endif ifeq ($(target_os_family),aix) @@ -1131,22 +1143,19 @@ ifdef unix_target libr_flags = -X32 endif - lib_link_libs += -lm -lc -lcurses - exe_link_libs += -lm -lc -lcurses + link_libs += -lm -lc -lcurses endif ifeq ($(target_os_family),hpux) ifeq ($(target_word_size),64) link_flags += +DD64 endif - lib_link_libs += -lm -lc -lrt -lcurses - exe_link_libs += -lm -lc -lrt -lcurses + link_libs += -lm -lc -lrt -lcurses endif ifeq ($(target_os_family),osx) shared_lib_suffix = -$(major_version).$(so_current).dylib - lib_link_libs += -lstdc++ -ldl -lncurses - exe_link_libs += -lstdc++ -ldl -lncurses + link_libs += -lstdc++ -ldl -lncurses shared_link_flags += -dynamiclib shared_link_flags += -current_version $(major_version).$(so_current).$(so_revision) shared_link_flags += -compatibility_version $(major_version).$(so_current).0 @@ -1541,18 +1550,18 @@ endif $(ftk_shared_lib_path) : $(ftk_obj) $(ec)$(gprintf) "Building $@ ...\n" ifdef win_target - $(ec)$(shared_linker) $(call hostpath,$+) $(shared_link_flags) $(lib_link_libs) + $(ec)$(shared_linker) $(call hostpath,$+) $(shared_link_flags) $(link_libs) endif ifdef unix_target $(ec)rm -f $@ - $(ec)$(shared_linker) $+ $(shared_link_flags) $(lib_link_libs) + $(ec)$(shared_linker) $+ $(shared_link_flags) $(link_libs) endif # -- Executable link command -- ifndef flm_exe_link_cmd define flm_exe_link_cmd - $(ec)$(exe_linker) $(exe_link_flags) $(allprereqs) $(exe_link_libs) + $(ec)$(exe_linker) $(exe_link_flags) $(allprereqs) $(link_libs) endef endif @@ -1765,7 +1774,7 @@ pkgconfig: dircheck $(ec)$(gprintf) "Name: $(package_proj_name)\n" >> $(pkgconfig_file) $(ec)$(gprintf) "Description: $(project_desc)\n" >> $(pkgconfig_file) $(ec)$(gprintf) "Version: $(version)\n" >> $(pkgconfig_file) - $(ec)$(gprintf) "Libs: $(exe_link_libs) -lftk -L$(dollar){libdir}\n" >> $(pkgconfig_file) + $(ec)$(gprintf) "Libs: $(link_libs) -lftk -L$(dollar){libdir}\n" >> $(pkgconfig_file) $(ec)$(gprintf) "Cflags: -I$(dollar){includedir}\n" >> $(pkgconfig_file) # -- SRCRPM -- @@ -2021,6 +2030,10 @@ nlm: ring0: $(ec)$(gprintf) "" +.PHONY : openssl +openssl: + $(ec)$(gprintf) "" + .PHONY : verbose verbose: $(ec)$(gprintf) "" diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index 6424740..5481ea1 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -626,12 +626,14 @@ flminterface IF_FileHdl; flminterface IF_FileSystem; flminterface IF_FileHdlCache; + flminterface IF_PrintfClient; flminterface IF_IStream; flminterface IF_PosIStream; flminterface IF_ResultSet; flminterface IF_ThreadInfo; flminterface IF_OStream; flminterface IF_IOStream; + flminterface IF_SSLIOStream; flminterface IF_LogMessageClient; flminterface IF_Thread; flminterface IF_IOBuffer; @@ -1349,7 +1351,7 @@ /**************************************************************************** Desc: ****************************************************************************/ - flminterface FLMEXP IF_IStream : public F_Object + flminterface FLMEXP IF_IStream : virtual public F_Object { virtual RCODE FLMAPI read( void * pvBuffer, @@ -1462,6 +1464,16 @@ IF_OStream * pOStream, IF_OStream ** ppOStream); + RCODE FLMAPI FlmAllocSSLIOStream( + IF_IOStream ** ppIOStream); + + RCODE FLMAPI FlmOpenSSLIOStream( + const char * pszTrustStore, + const char * pszHost, + FLMUINT uiPort, + FLMUINT uiFlags, + IF_IOStream ** ppIOStream); + RCODE FLMAPI FlmRemoveMultiFileStream( const char * pszDirectory, const char * pszBaseName); @@ -1474,6 +1486,14 @@ IF_IStream * pIStream, F_DynaBuf * pDynaBuf); + RCODE FLMAPI FlmReadLine( + IF_IStream * pIStream, + F_DynaBuf * pBuffer); + + void FLMAPI f_streamPrintf( + IF_OStream * pStream, + const char * pszFormatStr, ...); + /**************************************************************************** Desc: ****************************************************************************/ @@ -1527,7 +1547,7 @@ /**************************************************************************** Desc: ****************************************************************************/ - flminterface FLMEXP IF_OStream : public F_Object + flminterface FLMEXP IF_OStream : virtual public F_Object { virtual RCODE FLMAPI write( const void * pvBuffer, @@ -1547,6 +1567,32 @@ #endif }; + /**************************************************************************** + Desc: + ****************************************************************************/ + flminterface IF_SSLIOStream : public IF_IOStream + { + virtual RCODE FLMAPI openStream( + const char * pszTrustStore, + const char * pszHost, + FLMUINT uiPort = 443, + FLMUINT uiFlags = 0) = 0; + + virtual RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead = NULL) = 0; + + virtual RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten = NULL) = 0; + + virtual const char * FLMAPI getPeerCertificateText( void) = 0; + + virtual RCODE FLMAPI closeStream( void) = 0; + }; + /**************************************************************************** /// Message severity. ****************************************************************************/ @@ -3005,6 +3051,7 @@ #define ASCII_TAB 0x09 #define ASCII_NEWLINE 0x0A + #define ASCII_LF 0x0A #define ASCII_CR 0x0D #define ASCII_CTRLZ 0x1A #define ASCII_SPACE 0x20 @@ -3801,6 +3848,24 @@ const char * pszFormat, ...); + FLMINT FLMAPI f_printf( + IF_PrintfClient * pClient, + const char * pszFormat, + ...); + + FLMINT FLMAPI f_vprintf( + IF_PrintfClient * pClient, + const char * pszFormat, + f_va_list * args); + + RCODE FLMAPI f_printf( + IF_OStream * pOStream, + const char * pszFormatStr, ...); + + RCODE FLMAPI f_vprintf( + IF_OStream * pOStream, + const char * pszFormatStr, ...); + /**************************************************************************** Desc: Memory copying, moving, setting ****************************************************************************/ @@ -3914,6 +3979,11 @@ FLMBYTE FLMAPI f_getBase24DigitChar( FLMBYTE ucValue); + RCODE FLMAPI f_stripCRLF( + const FLMBYTE * pucSourceBuf, + FLMUINT uiSourceLength, + F_DynaBuf * pDestBuf); + #define shiftN(data,size,distance) \ f_memmove((FLMBYTE *)(data) + (FLMINT)(distance), \ (FLMBYTE *)(data), (unsigned)(size)) @@ -3921,186 +3991,23 @@ /*************************************************************************** Desc: ***************************************************************************/ - class FLMEXP F_Printf : public F_Object + flminterface FLMEXP IF_PrintfClient : public F_Object { - public: - - #define MAX_LOG_BUF_CHARS 255 - - F_Printf() - { - } - - virtual ~F_Printf() - { - } - - FLMINT FLMAPI strvPrintf( - char * pszDestStr, - const char * pszFormat, - f_va_list * args); - - FLMINT FLMAPI strPrintf( - char * pszDestStr, - const char * pszFormat, - ...); - - FLMINT FLMAPI logvPrintf( - IF_LogMessageClient * pLogMsg, - const char * pszFormat, - f_va_list * args); + virtual FLMINT FLMAPI outputChar( + char cChar) = 0; - FLMINT FLMAPI logPrintf( - IF_LogMessageClient * pLogMsg, - const char * pszFormat, - ...); + virtual FLMINT FLMAPI outputChar( + char cChar, + FLMUINT uiCount) = 0; - private: - - void processFieldInfo( - const char ** ppszFormat, - FLMUINT * puiWidth, - FLMUINT * puiPrecision, - FLMUINT * puiFlags, - f_va_list * args); - - void stringFormatter( - char cFormatChar, - FLMUINT uiWidth, - FLMUINT uiPrecision, - FLMUINT uiFlags, - f_va_list * args); - - void colorFormatter( + virtual FLMINT FLMAPI outputStr( + const char * pszStr, + FLMUINT uiLen) = 0; + + virtual FLMINT FLMAPI colorFormatter( char cFormatChar, eColorType eColor, - FLMUINT uiFlags); - - void charFormatter( - char cFormatChar, - f_va_list * args); - - void errorFormatter( - f_va_list * args); - - void notHandledFormatter( void); - - void numberFormatter( - char cFormatChar, - FLMUINT uiWidth, - FLMUINT uiPrecision, - FLMUINT uiFlags, - f_va_list * args); - - void parseArgs( - const char * pszFormat, - f_va_list * args); - - void processFormatString( - FLMUINT uiLen, - ...); - - FLMUINT printNumber( - FLMUINT64 ui64Val, - FLMUINT uiBase, - FLMBOOL bUpperCase, - FLMBOOL bCommas, - char * pszBuf); - - void outputLogBuffer( void); - - FINLINE void outputChar( - char cChar) - { - if (!m_pLogMsg) - { - *m_pszDestStr++ = cChar; - } - else - { - m_szLogBuf [m_uiCharOffset++] = cChar; - m_uiNumLogChars++; - if (m_uiCharOffset == MAX_LOG_BUF_CHARS) - { - outputLogBuffer(); - } - } - } - - FINLINE void memsetChar( - char cChar, - FLMUINT uiCount) - { - if (!m_pLogMsg) - { - f_memset( m_pszDestStr, cChar, uiCount); - m_pszDestStr += uiCount; - } - else - { - FLMUINT uiTmpCount; - - while (uiCount) - { - uiTmpCount = uiCount; - if (m_uiCharOffset + uiTmpCount > MAX_LOG_BUF_CHARS) - { - uiTmpCount = MAX_LOG_BUF_CHARS - m_uiCharOffset; - } - f_memset( &m_szLogBuf [m_uiCharOffset], cChar, uiTmpCount); - m_uiCharOffset += uiTmpCount; - m_uiNumLogChars += uiTmpCount; - uiCount -= uiTmpCount; - if (m_uiCharOffset == MAX_LOG_BUF_CHARS) - { - outputLogBuffer(); - } - } - } - } - - FINLINE void outputStr( - const char * pszStr, - FLMUINT uiLen) - { - if (!m_pLogMsg) - { - f_memcpy( m_pszDestStr, pszStr, uiLen); - m_pszDestStr += uiLen; - } - else - { - FLMUINT uiTmpLen; - - while (uiLen) - { - uiTmpLen = uiLen; - if (m_uiCharOffset + uiTmpLen > MAX_LOG_BUF_CHARS) - { - uiTmpLen = MAX_LOG_BUF_CHARS - m_uiCharOffset; - } - f_memcpy( &m_szLogBuf [m_uiCharOffset], pszStr, uiTmpLen); - m_uiCharOffset += uiTmpLen; - m_uiNumLogChars += uiTmpLen; - uiLen -= uiTmpLen; - pszStr += uiTmpLen; - if (m_uiCharOffset == MAX_LOG_BUF_CHARS) - { - outputLogBuffer(); - } - } - } - } - - // Variables used to do the printf stuff - - char m_szLogBuf [MAX_LOG_BUF_CHARS + 1]; - FLMUINT m_uiNumLogChars; - FLMUINT m_uiCharOffset; - char * m_pszDestStr; - IF_LogMessageClient * m_pLogMsg; - eColorType m_eCurrentForeColor; - eColorType m_eCurrentBackColor; + FLMUINT uiFlags) = 0; }; /**************************************************************************** @@ -6630,6 +6537,11 @@ FLMBYTE m_ucBuffer[ 8]; }; + RCODE FLMAPI f_base64Encode( + const char * pData, + FLMUINT uiDataLength, + F_DynaBuf * pBuffer); + /**************************************************************************** Desc: Encodes a binary input stream into ASCII base64. ****************************************************************************/ diff --git a/ftk/src/ftklog.cpp b/ftk/src/ftklog.cpp index 2c033dd..30a1c42 100644 --- a/ftk/src/ftklog.cpp +++ b/ftk/src/ftklog.cpp @@ -29,6 +29,120 @@ static F_MUTEX gv_hLoggerMutex = F_MUTEX_NULL; static FLMUINT gv_uiPendingLogMessages = 0; static IF_LoggerClient * gv_pLogger = NULL; +/*************************************************************************** +Desc: +***************************************************************************/ +class FLMEXP F_LogPrintfClient : public IF_PrintfClient +{ +public: + +#define MAX_LOG_BUF_CHARS 255 + + F_LogPrintfClient( IF_LogMessageClient * pLogMsg) + { + m_pLogMsg = pLogMsg; + m_pLogMsg->AddRef(); + } + + virtual ~F_LogPrintfClient() + { + if( m_pLogMsg) + { + m_pLogMsg->Release(); + m_pLogMsg = NULL; + } + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar, + FLMUINT uiCount) + { + FLMUINT uiTmpCount; + FLMINT iBytesOutput = (FLMINT)uiCount; + + while( uiCount) + { + uiTmpCount = uiCount; + + if( m_uiCharOffset + uiTmpCount > MAX_LOG_BUF_CHARS) + { + uiTmpCount = MAX_LOG_BUF_CHARS - m_uiCharOffset; + } + + f_memset( &m_szLogBuf [m_uiCharOffset], cChar, uiTmpCount); + + m_uiCharOffset += uiTmpCount; + uiCount -= uiTmpCount; + + if (m_uiCharOffset == MAX_LOG_BUF_CHARS) + { + outputLogBuffer(); + } + } + + return( iBytesOutput); + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar) + { + m_szLogBuf[ m_uiCharOffset++] = cChar; + + if( m_uiCharOffset == MAX_LOG_BUF_CHARS) + { + outputLogBuffer(); + } + + return( 1); + } + + FINLINE FLMINT FLMAPI outputStr( + const char * pszStr, + FLMUINT uiLen) + { + FLMUINT uiTmpLen; + FLMINT iBytesOutput = (FLMINT)uiLen; + + while( uiLen) + { + uiTmpLen = uiLen; + + if( m_uiCharOffset + uiTmpLen > MAX_LOG_BUF_CHARS) + { + uiTmpLen = MAX_LOG_BUF_CHARS - m_uiCharOffset; + } + + f_memcpy( &m_szLogBuf [m_uiCharOffset], pszStr, uiTmpLen); + + m_uiCharOffset += uiTmpLen; + uiLen -= uiTmpLen; + pszStr += uiTmpLen; + + if (m_uiCharOffset == MAX_LOG_BUF_CHARS) + { + outputLogBuffer(); + } + } + + return( iBytesOutput); + } + + FLMINT FLMAPI colorFormatter( + char cFormatChar, + eColorType eColor, + FLMUINT uiFlags); + +private: + + void outputLogBuffer( void); + + char m_szLogBuf [MAX_LOG_BUF_CHARS + 1]; + FLMUINT m_uiCharOffset; + IF_LogMessageClient * m_pLogMsg; + eColorType m_eCurrentForeColor; + eColorType m_eCurrentBackColor; +}; + /**************************************************************************** Desc: Main entry point for printf functionality. ****************************************************************************/ @@ -36,11 +150,11 @@ void f_logPrintf( IF_LogMessageClient * pLogMessage, const char * pszFormatStr, ...) { - f_va_list args; - F_Printf formatter; + f_va_list args; + F_LogPrintfClient printfClient( pLogMessage); f_va_start( args, pszFormatStr); - formatter.logvPrintf( pLogMessage, pszFormatStr, &args); + f_vprintf( &printfClient, pszFormatStr, &args); f_va_end( args); } @@ -52,9 +166,9 @@ void FLMAPI f_logVPrintf( const char * pszFormatStr, f_va_list * args) { - F_Printf formatter; + F_LogPrintfClient printfClient( pLogMessage); - formatter.logvPrintf( pLogMessage, pszFormatStr, args); + f_vprintf( &printfClient, pszFormatStr, args); } /**************************************************************************** @@ -65,7 +179,7 @@ IF_LogMessageClient * FLMAPI f_beginLogMessage( FLMUINT uiMsgType, eLogMessageSeverity eMsgSeverity) { - IF_LogMessageClient * pNewMsg = NULL; + IF_LogMessageClient * pNewMsg = NULL; f_mutexLock( gv_hLoggerMutex); @@ -139,9 +253,9 @@ Desc: Initialize the toolkit logger ****************************************************************************/ RCODE f_loggerInit( void) { - RCODE rc = NE_FLM_OK; + RCODE rc = NE_FLM_OK; - if (RC_BAD( rc = f_mutexCreate( &gv_hLoggerMutex))) + if( RC_BAD( rc = f_mutexCreate( &gv_hLoggerMutex))) { goto Exit; } @@ -156,12 +270,13 @@ Desc: Shutdown the toolkit logger ****************************************************************************/ void f_loggerShutdown( void) { - if (gv_pLogger) + if( gv_pLogger) { gv_pLogger->Release(); gv_pLogger = NULL; } - if (gv_hLoggerMutex != F_MUTEX_NULL) + + if( gv_hLoggerMutex != F_MUTEX_NULL) { f_mutexDestroy( &gv_hLoggerMutex); } @@ -174,14 +289,84 @@ void f_setLoggerClient( IF_LoggerClient * pLogger) { f_mutexLock( gv_hLoggerMutex); - if (gv_pLogger) + + if( gv_pLogger) { gv_pLogger->Release(); } - if ((gv_pLogger = pLogger) != NULL) + + if( (gv_pLogger = pLogger) != NULL) { gv_pLogger->AddRef(); } + f_mutexUnlock( gv_hLoggerMutex); } +/**************************************************************************** +Desc: Output the current log buffer - only called when logging. +****************************************************************************/ +void F_LogPrintfClient::outputLogBuffer( void) +{ + if( m_uiCharOffset) + { + m_szLogBuf[ m_uiCharOffset] = 0; + m_pLogMsg->appendString( m_szLogBuf); + m_uiCharOffset = 0; + } +} + +/**************************************************************************** +Desc: Change colors - may only push or pop a color on to the color stack. +****************************************************************************/ +FLMINT FLMAPI F_LogPrintfClient::colorFormatter( + char cFormatChar, + eColorType eColor, + FLMUINT uiFlags) +{ + // Color formatting is ignored if there is not a log message object. + + if( m_pLogMsg) + { + + // Before changing colors, output the current log buffer. + + outputLogBuffer(); + + if( cFormatChar == 'F') // Foreground color + { + if( uiFlags & FLM_PRINTF_PLUS_FLAG) + { + m_pLogMsg->pushForegroundColor(); + } + else if( uiFlags & FLM_PRINTF_MINUS_FLAG) + { + m_pLogMsg->popForegroundColor(); + } + else if( m_eCurrentForeColor != eColor) + { + m_eCurrentForeColor = eColor; + m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); + } + } + else // cFormatChar == 'B' - background color + { + if( uiFlags & FLM_PRINTF_PLUS_FLAG) + { + m_pLogMsg->pushBackgroundColor(); + } + else if( uiFlags & FLM_PRINTF_MINUS_FLAG) + { + m_pLogMsg->popBackgroundColor(); + } + else if( m_eCurrentBackColor != eColor) + { + m_eCurrentBackColor = eColor; + m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); + } + } + } + + return( 0); +} + diff --git a/ftk/src/ftkmisc.cpp b/ftk/src/ftkmisc.cpp index ca4d023..5159af3 100644 --- a/ftk/src/ftkmisc.cpp +++ b/ftk/src/ftkmisc.cpp @@ -223,6 +223,14 @@ RCODE FLMAPI ftkStartup( void) } #endif +#if defined( FLM_OPENSSL) + // Initialize OpenSSL + + SSL_load_error_strings(); + SSL_library_init(); + ERR_load_BIO_strings(); +#endif + // Setup logger if (RC_BAD( rc = f_loggerInit())) @@ -3052,3 +3060,83 @@ void f_freeFileAsyncClientList( void) F_FileHdl::m_uiAvailAsyncCount = 0; } + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_stripCRLF( + const FLMBYTE * pucSourceBuf, + FLMUINT uiSourceLength, + F_DynaBuf * pDestBuf) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiLoop; + FLMBYTE ucSourceChar; + + for( uiLoop = 0; uiLoop < uiSourceLength; uiLoop++) + { + ucSourceChar = pucSourceBuf[ uiLoop]; + + if( ucSourceChar != ASCII_CR && ucSourceChar != ASCII_NEWLINE) + { + if( RC_BAD( rc = pDestBuf->appendByte( ucSourceChar))) + { + goto Exit; + } + + if( !ucSourceChar) + { + break; + } + } + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_base64Encode( + const char * pData, + FLMUINT uiDataLength, + F_DynaBuf * pBuffer) +{ + RCODE rc = NE_FLM_OK; + IF_PosIStream * pBufferStream = NULL; + IF_IStream * pEncodedStream = NULL; + + if( RC_BAD( rc = FlmOpenBufferIStream( pData, + uiDataLength, &pBufferStream))) + { + goto Exit; + } + + if( RC_BAD( rc = FlmOpenBase64EncoderIStream( pBufferStream, + FALSE, &pEncodedStream))) + { + goto Exit; + } + + if( RC_BAD( rc = FlmReadFully( pEncodedStream, pBuffer))) + { + goto Exit; + } + +Exit: + + if( pEncodedStream) + { + pEncodedStream->Release(); + } + + if( pBufferStream) + { + pBufferStream->Release(); + } + + return( rc); +} + diff --git a/ftk/src/ftknlm.cpp b/ftk/src/ftknlm.cpp index a8a90a5..b0f50eb 100644 --- a/ftk/src/ftknlm.cpp +++ b/ftk/src/ftknlm.cpp @@ -600,8 +600,13 @@ FLMATOMIC gv_NetWareStartupCount = 0; rtag_t gv_lAllocRTag = 0; - static FLMINT64 gv_NssRootKey; - static FLMBOOL gv_bNSSKeyInitialized = FALSE; + FSTATIC FLMINT64 gv_NssRootKey; + FSTATIC FLMBOOL gv_bNSSKeyInitialized = FALSE; + FSTATIC SEMAPHORE gv_lFlmSyncSem = 0; + FSTATIC FLMBOOL gv_bUnloadCalled = FALSE; + FSTATIC FLMBOOL gv_bMainRunning = FALSE; + FSTATIC F_EXIT_FUNC gv_fnExit = NULL; + extern FLMATOMIC gv_openFiles; #if !defined( __MWERKS__) extern unsigned long ReadInternalClock(void); @@ -637,8 +642,14 @@ FLMINT lStatus, RCODE defaultRc); - extern FLMATOMIC gv_openFiles; + RCODE f_nssInitialize( void); + void f_nssUninitialize( void); + + extern "C" int nlm_main( + int iArgC, + char ** ppszArgV); + #endif /*************************************************************************** @@ -3554,6 +3565,409 @@ Exit: } #endif +/******************************************************************** +Desc: Startup routine for the NLM - that gets the main going in + its own thread. +*********************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +extern "C" void * f_nlmMainStub( + void * hThread, + void * pData) +{ + ARG_DATA * pArgData = (ARG_DATA *)pData; + struct LoadDefinitionStructure * moduleHandle = pArgData->moduleHandle; + + (void)hThread; + + (void)kSetThreadName( (void *)kCurrentThread(), + (BYTE *)pArgData->pszThreadName); + + nlm_main( pArgData->iArgC, pArgData->ppszArgV); + + Free( pArgData->ppszArgV); + Free( pArgData->pszArgs); + Free( pArgData->pszThreadName); + Free( pArgData); + + gv_bMainRunning = FALSE; + + if( !gv_bUnloadCalled) + { + KillMe( moduleHandle); + } + + kExitThread( NULL); + return( NULL); +} +#endif + +/******************************************************************** +Desc: Signals the f_nlmEntryPoint thread to release the console. +*********************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +void SynchronizeStart( void) +{ + if (gv_lFlmSyncSem) + { + (void)kSemaphoreSignal( gv_lFlmSyncSem); + } +} +#endif + +/******************************************************************** +Desc: Startup routine for the NLM. +*********************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +extern "C" LONG f_nlmEntryPoint( + struct LoadDefinitionStructure * moduleHandle, + struct ScreenStruct * initScreen, + char * commandLine, + char * loadDirectoryPath, + LONG uninitializedDataLength, + LONG fileHandle, + LONG (*ReadRoutine) + (LONG handle, + LONG offset, + char * buffer, + LONG length), + LONG customDataOffset, + LONG customDataSize) +{ + char * pszTmp; + char * pszArgStart; + int iArgC; + int iTotalArgChars; + int iArgSize; + char ** ppszArgV = NULL; + char * pszArgs = NULL; + char * pszDestArg; + bool bFirstPass = true; + char cEnd; + ARG_DATA * pArgData = NULL; + LONG sdRet = 0; + char * pszThreadName; + char * pszModuleName; + int iModuleNameLen; + int iThreadNameLen; + int iLoadDirPathSize; + void * hThread = NULL; + + (void)initScreen; + (void)uninitializedDataLength; + (void)fileHandle; + (void)ReadRoutine; + (void)customDataOffset; + (void)customDataSize; + + if( f_atomicInc( &gv_NetWareStartupCount) != 1) + { + goto Exit; + } + + gv_MyModuleHandle = moduleHandle; + gv_bUnloadCalled = FALSE; + + // Allocate the needed resource tags + + if( (gv_lAllocRTag = AllocateResourceTag( gv_MyModuleHandle, + "FLAIM Memory", AllocSignature)) == NULL) + { + sdRet = 1; + goto Exit; + } + + // Syncronized start + + if (moduleHandle->LDFlags & 4) + { + gv_lFlmSyncSem = kSemaphoreAlloc( (BYTE *)"FLAIM_SYNC", 0); + } + + // Initialize NSS + + if( RC_BAD( f_nssInitialize())) + { + sdRet = 1; + goto Exit; + } + + pszModuleName = (char *)(&moduleHandle->LDFileName[ 1]); + iModuleNameLen = (int)(moduleHandle->LDFileName[ 0]); + + // First pass: Count the arguments in the command line + // and determine how big of a buffer we will need. + // Second pass: Put argments into allocated buffer. + +Parse_Args: + + iTotalArgChars = 0; + iArgC = 0; + + iLoadDirPathSize = f_strlen( (const char *)loadDirectoryPath); + iArgSize = iLoadDirPathSize + iModuleNameLen; + + if( !bFirstPass) + { + ppszArgV[ iArgC] = pszDestArg; + f_memcpy( pszDestArg, loadDirectoryPath, iLoadDirPathSize); + f_memcpy( &pszDestArg[ iLoadDirPathSize], pszModuleName, iModuleNameLen); + pszDestArg[ iArgSize] = 0; + pszDestArg += (iArgSize + 1); + } + + iArgC++; + iTotalArgChars += iArgSize; + pszTmp = commandLine; + + for (;;) + { + // Skip leading blanks. + + while( *pszTmp && *pszTmp == ' ') + { + pszTmp++; + } + + if( *pszTmp == 0) + { + break; + } + + if( *pszTmp == '"' || *pszTmp == '\'') + { + cEnd = *pszTmp; + pszTmp++; + } + else + { + cEnd = ' '; + } + + pszArgStart = pszTmp; + iArgSize = 0; + + // Count the characters in the parameter. + + while( *pszTmp && *pszTmp != cEnd) + { + iArgSize++; + pszTmp++; + } + + if( !iArgSize && cEnd == ' ') + { + break; + } + + // If 2nd pass, save the argument. + + if( !bFirstPass) + { + ppszArgV[ iArgC] = pszDestArg; + + if( iArgSize) + { + f_memcpy( pszDestArg, pszArgStart, iArgSize); + } + + pszDestArg[ iArgSize] = 0; + pszDestArg += (iArgSize + 1); + } + + iArgC++; + iTotalArgChars += iArgSize; + + // Skip trailing quote or blank. + + if( *pszTmp) + { + pszTmp++; + } + } + + if( bFirstPass) + { + if ((ppszArgV = (char **)Alloc( sizeof( char *) * iArgC, + gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + if( (pszArgs = (char *)Alloc( iTotalArgChars + iArgC, + gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + pszDestArg = pszArgs; + bFirstPass = false; + goto Parse_Args; + } + + iThreadNameLen = (int)(moduleHandle->LDName[ 0]); + + if( (pszThreadName = (char *)Alloc( iThreadNameLen + 1, gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + f_memcpy( pszThreadName, (char *)(&moduleHandle->LDName[ 1]), iThreadNameLen); + pszThreadName[ iThreadNameLen] = 0; + + if( (pArgData = (ARG_DATA *)Alloc( sizeof( ARG_DATA), + gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + pArgData->ppszArgV = ppszArgV; + pArgData->pszArgs = pszArgs; + pArgData->iArgC = iArgC; + pArgData->moduleHandle = moduleHandle; + pArgData->pszThreadName = pszThreadName; + + gv_bMainRunning = TRUE; + + if( (hThread = kCreateThread( (BYTE *)"FTK main", + f_nlmMainStub, NULL, 32768, (void *)pArgData)) == NULL) + { + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + if( kSetThreadLoadHandle( hThread, (LONG)moduleHandle) != 0) + { + (void)kDestroyThread( hThread); + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + if( kScheduleThread( hThread) != 0) + { + (void)kDestroyThread( hThread); + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + // Synchronized start + + if( moduleHandle->LDFlags & 4) + { + (void)kSemaphoreWait( gv_lFlmSyncSem); + } + +Exit: + + if( sdRet != 0) + { + f_atomicDec( &gv_NetWareStartupCount); + + if( ppszArgV) + { + Free( ppszArgV); + } + + if( pszArgs) + { + Free( pszArgs); + } + + if( pszThreadName) + { + Free( pszThreadName); + } + + if( pArgData) + { + Free( pArgData); + } + + if( gv_lFlmSyncSem) + { + kSemaphoreFree( gv_lFlmSyncSem); + gv_lFlmSyncSem = 0; + } + + if( !gv_bUnloadCalled) + { + KillMe( moduleHandle); + } + } + + return( sdRet); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +extern "C" void f_nlmExitPoint(void) +{ + if( f_atomicDec( &gv_NetWareStartupCount) > 0) + { + return; + } + + gv_bUnloadCalled = TRUE; + + if( gv_fnExit) + { + (*gv_fnExit)(); + gv_fnExit = NULL; + } + + while( gv_bMainRunning) + { + kYieldThread(); + } + + f_nssUninitialize(); + + if( gv_lFlmSyncSem) + { + kSemaphoreFree( gv_lFlmSyncSem); + gv_lFlmSyncSem = 0; + } + + if( gv_lAllocRTag) + { + ReturnResourceTag( gv_lAllocRTag, 1); + gv_lAllocRTag = 0; + } +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +extern "C" void exit( + int exitCode) +{ + (void)exitCode; +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#if defined( FLM_RING_ZERO_NLM) +extern "C" int atexit( + F_EXIT_FUNC fnExit) +{ + gv_fnExit = fnExit; + return( 0); +} +#endif + /**************************************************************************** Desc: ****************************************************************************/ @@ -3563,3 +3977,4 @@ int ftknlmDummy( void) return( 0); } #endif + diff --git a/ftk/src/ftkprntf.cpp b/ftk/src/ftkprntf.cpp index 0ab0125..7f73ca6 100644 --- a/ftk/src/ftkprntf.cpp +++ b/ftk/src/ftkprntf.cpp @@ -25,6 +25,126 @@ #include "ftksys.h" +/**************************************************************************** +Desc: +****************************************************************************/ +class FLMEXP F_BufferPrintfClient : public IF_PrintfClient +{ +public: + + F_BufferPrintfClient( char * pszDestBuffer) + { + m_pszDestBuffer = pszDestBuffer; + } + + virtual ~F_BufferPrintfClient() + { + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar) + { + *m_pszDestBuffer++ = cChar; + return( 1); + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar, + FLMUINT uiCount) + { + f_memset( m_pszDestBuffer, cChar, uiCount); + m_pszDestBuffer += uiCount; + + return( (FLMINT)uiCount); + } + + FINLINE FLMINT FLMAPI outputStr( + const char * pszStr, + FLMUINT uiLen) + { + f_memcpy( m_pszDestBuffer, pszStr, uiLen); + m_pszDestBuffer += uiLen; + + return( (FLMINT)uiLen); + } + + FINLINE FLMINT FLMAPI colorFormatter( + char, // cFormatChar, + eColorType, // eColor, + FLMUINT) // uiFlags) + { + return( 0); + } + +private: + + char * m_pszDestBuffer; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class FLMEXP F_DynaPrintfClient : public IF_PrintfClient +{ +public: + + F_DynaPrintfClient() : m_dynaBuf( m_ucBuffer, sizeof( m_ucBuffer)) + { + } + + virtual ~F_DynaPrintfClient() + { + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar) + { + m_dynaBuf.appendByte( cChar); + return( 1); + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar, + FLMUINT uiCount) + { + FLMINT iBytesOutput = (FLMINT)uiCount; + + while( uiCount) + { + m_dynaBuf.appendByte( cChar); + uiCount--; + } + + return( iBytesOutput); + } + + FINLINE FLMINT FLMAPI outputStr( + const char * pszStr, + FLMUINT uiLen) + { + m_dynaBuf.appendData( pszStr, uiLen); + return( (FLMINT)uiLen); + } + + FINLINE FLMINT FLMAPI colorFormatter( + char, // cFormatChar, + eColorType, // eColor, + FLMUINT) // uiFlags) + { + return( 0); + } + + FINLINE const char * getBufferPtr( void) + { + return( (const char *)m_dynaBuf.getBufferPtr()); + } + +private: + + FLMBYTE m_ucBuffer[ 256]; + F_DynaBuf m_dynaBuf; +}; + /**************************************************************************** Desc: Parameter 'format' points to text following a '%' sign. Process legal field information. Leave 'format' pointing at the format @@ -42,6 +162,7 @@ void F_Printf::processFieldInfo( // Process flags *puiFlags = 0; + for( ;;) { switch( *pszFormat) @@ -82,6 +203,7 @@ NoMoreFlags: // Process width *puiWidth = 0; + if( *pszFormat == '*') { *puiWidth = f_va_arg( *args, unsigned int); @@ -99,9 +221,11 @@ NoMoreFlags: // Process precision *puiPrecision = 0; + if( *pszFormat == '.') { pszFormat++; + if( *pszFormat == '*') { *puiPrecision = f_va_arg( *args, unsigned int); @@ -115,6 +239,7 @@ NoMoreFlags: } // Size modifiers + switch( *pszFormat) { case 'I': @@ -153,7 +278,7 @@ NoMoreFlags: Desc: Handle text portions of the format string ****************************************************************************/ void F_Printf::processFormatString( - FLMUINT uiLen, + FLMUINT uiLen, ...) { f_va_list args; @@ -169,15 +294,17 @@ void F_Printf::processFormatString( /**************************************************************************** Desc: Parse arguments in format string, calling appropriate handlers ****************************************************************************/ -void F_Printf::parseArgs( +FLMINT F_Printf::parseArgs( const char * pszFormat, f_va_list * args) { - char cFormatChar; - FLMUINT uiFlags; - FLMUINT uiWidth; - FLMUINT uiPrecision; - const char * pszTextStart = pszFormat; + char cFormatChar; + FLMUINT uiFlags; + FLMUINT uiWidth; + FLMUINT uiPrecision; + const char * pszTextStart = pszFormat; + + m_iBytesOutput = 0; while( (cFormatChar = *pszFormat++) != 0) { @@ -217,14 +344,8 @@ void F_Printf::parseArgs( case 'B': case 'F': - - // If we are not outputting a log message, colors are simply - // stripped out. - - if (m_pLogMsg) - { - colorFormatter( cFormatChar, (eColorType)uiWidth, uiFlags); - } + m_iBytesOutput += m_pClient->colorFormatter( cFormatChar, + (eColorType)uiWidth, uiFlags); break; case 's': @@ -242,10 +363,12 @@ void F_Printf::parseArgs( notHandledFormatter(); break; } + pszTextStart = pszFormat; } processFormatString( (FLMUINT)(pszFormat - pszTextStart - 1), pszTextStart); + return( m_iBytesOutput); } /**************************************************************************** @@ -264,20 +387,21 @@ void F_Printf::stringFormatter( FLMUNICODE * pUnicode; const char * pszStr = f_va_arg( *args, char *); - if (!pszStr) + if( !pszStr) { uiOutputLen = f_strlen( pszNullPointerStr); } - else if (cFormatChar == 'S') + else if( cFormatChar == 'S') { uiOutputLen = *pszStr++; } else { - if (cFormatChar == 'U') + if( cFormatChar == 'U') { uiOutputLen = 0; pUnicode = (FLMUNICODE *)pszStr; + while( *pUnicode) { if( *pUnicode >= 32 && *pUnicode <= 127) @@ -288,6 +412,7 @@ void F_Printf::stringFormatter( { uiOutputLen += 7; } + pUnicode++; } } @@ -297,24 +422,25 @@ void F_Printf::stringFormatter( } } - if (uiPrecision > 0 && uiOutputLen > uiPrecision) + if( uiPrecision > 0 && uiOutputLen > uiPrecision) { uiOutputLen = uiPrecision; } uiCount = uiWidth - uiOutputLen; - if (uiOutputLen < uiWidth && !(uiFlags & FLM_PRINTF_MINUS_FLAG)) + if( uiOutputLen < uiWidth && !(uiFlags & FLM_PRINTF_MINUS_FLAG)) { // Right justify - memsetChar( ' ', uiCount); + + m_iBytesOutput += m_pClient->outputChar( ' ', uiCount); } if( !pszStr) { - outputStr( pszNullPointerStr, uiOutputLen); + m_iBytesOutput += m_pClient->outputStr( pszNullPointerStr, uiOutputLen); } - else if (cFormatChar == 'U') + else if( cFormatChar == 'U') { FLMUINT uiBytesOutput = 0; @@ -323,7 +449,7 @@ void F_Printf::stringFormatter( { if( *pUnicode >= 32 && *pUnicode <= 127) { - outputChar( (char)(*pUnicode)); + m_iBytesOutput += m_pClient->outputChar( (char)(*pUnicode)); uiBytesOutput++; } else @@ -339,95 +465,25 @@ void F_Printf::stringFormatter( szTmpBuf[ uiTmpLen] = ']'; szTmpBuf[ uiTmpLen + 1] = 0; - if ((uiBytesOutput = uiTmpLen + 2) > uiOutputLen) + if( (uiBytesOutput = uiTmpLen + 2) > uiOutputLen) { uiBytesOutput = uiOutputLen; } - outputStr( szTmpBuf, uiBytesOutput); + m_iBytesOutput += m_pClient->outputStr( szTmpBuf, uiBytesOutput); } } } else { - outputStr( pszStr, uiOutputLen); + m_iBytesOutput += m_pClient->outputStr( pszStr, uiOutputLen); } if (uiOutputLen < uiWidth && (uiFlags & FLM_PRINTF_MINUS_FLAG)) { // Left justify - memsetChar( ' ', uiCount); - } -} - -/**************************************************************************** -Desc: Output the current log buffer - only called when logging. -****************************************************************************/ -void F_Printf::outputLogBuffer( void) -{ - if (m_uiCharOffset) - { - m_szLogBuf [m_uiCharOffset] = 0; - - m_pLogMsg->appendString( m_szLogBuf); - - // Reset to start filling from the beginning of the buffer. - - m_uiCharOffset = 0; - } -} - -/**************************************************************************** -Desc: Change colors - may only push or pop a color on to the color stack. -****************************************************************************/ -void F_Printf::colorFormatter( - char cFormatChar, - eColorType eColor, - FLMUINT uiFlags) -{ - - // Color formatting is ignored if there is not a log message object. - - if (m_pLogMsg) - { - - // Before changing colors, output the current log buffer. - - outputLogBuffer(); - - if (cFormatChar == 'F') // Foreground color - { - if (uiFlags & FLM_PRINTF_PLUS_FLAG) - { - m_pLogMsg->pushForegroundColor(); - } - else if (uiFlags & FLM_PRINTF_MINUS_FLAG) - { - m_pLogMsg->popForegroundColor(); - } - else if (m_eCurrentForeColor != eColor) - { - m_eCurrentForeColor = eColor; - m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); - } - } - else // cFormatChar == 'B' - background color - { - if (uiFlags & FLM_PRINTF_PLUS_FLAG) - { - m_pLogMsg->pushBackgroundColor(); - } - else if (uiFlags & FLM_PRINTF_MINUS_FLAG) - { - m_pLogMsg->popBackgroundColor(); - } - else if (m_eCurrentBackColor != eColor) - { - m_eCurrentBackColor = eColor; - m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); - } - } + m_iBytesOutput += m_pClient->outputChar( ' ', uiCount); } } @@ -441,10 +497,10 @@ FLMUINT F_Printf::printNumber( FLMBOOL bCommas, char * pszBuf) { - char cChar; - FLMUINT uiOffset = 0; - FLMUINT uiDigitCount = 0; - FLMUINT uiLoop; + char cChar; + FLMUINT uiOffset = 0; + FLMUINT uiDigitCount = 0; + FLMUINT uiLoop; // We don't support commas on bases other than 10 @@ -498,20 +554,20 @@ void F_Printf::numberFormatter( FLMUINT uiFlags, f_va_list * args) { - FLMUINT uiPrefix = FLM_PREFIX_NONE; - FLMUINT uiLength; - FLMUINT uiBase = 10; - char cNumberBuffer[ 64]; - FLMBOOL bUpperCase = FALSE; - FLMBOOL bCommas = FALSE; - FLMUINT64 ui64Val; + FLMUINT uiPrefix = FLM_PREFIX_NONE; + FLMUINT uiLength; + FLMUINT uiBase = 10; + char cNumberBuffer[ 64]; + FLMBOOL bUpperCase = FALSE; + FLMBOOL bCommas = FALSE; + FLMUINT64 ui64Val; - if (cFormatChar == 'p') + if( cFormatChar == 'p') { ui64Val = (FLMUINT64)((FLMUINT)f_va_arg( *args, void *)); uiFlags |= FLM_PRINTF_POUND_FLAG; } - else if (cFormatChar != 'd') + else if( cFormatChar != 'd') { // Unsigned number @@ -536,15 +592,15 @@ void F_Printf::numberFormatter( { // Signed number - if (uiFlags & FLM_PRINTF_SHORT_FLAG) + if( uiFlags & FLM_PRINTF_SHORT_FLAG) { ui64Val = (FLMUINT64)((FLMINT64)f_va_arg( *args, int)); } - else if (uiFlags & (FLM_PRINTF_LONG_FLAG | FLM_PRINTF_DOUBLE_FLAG)) + else if( uiFlags & (FLM_PRINTF_LONG_FLAG | FLM_PRINTF_DOUBLE_FLAG)) { ui64Val = (FLMUINT64)((FLMINT64)f_va_arg( *args, long int)); } - else if (uiFlags & FLM_PRINTF_INT64_FLAG) + else if( uiFlags & FLM_PRINTF_INT64_FLAG) { ui64Val = (FLMUINT64)f_va_arg( *args, FLMINT64); } @@ -554,7 +610,7 @@ void F_Printf::numberFormatter( } } - switch (cFormatChar) + switch( cFormatChar) { case 'd': { @@ -588,7 +644,7 @@ void F_Printf::numberFormatter( case 'X': case 'p': { - if ((uiFlags & FLM_PRINTF_POUND_FLAG) && ui64Val) + if( (uiFlags & FLM_PRINTF_POUND_FLAG) && ui64Val) { uiPrefix = FLM_PREFIX_POUND; if( uiWidth > 1) @@ -601,58 +657,58 @@ void F_Printf::numberFormatter( } } - if (cFormatChar == 'X') + if( cFormatChar == 'X') { bUpperCase = TRUE; } - if ((uiFlags & FLM_PRINTF_COMMA_FLAG) && uiBase == 10) + if( (uiFlags & FLM_PRINTF_COMMA_FLAG) && uiBase == 10) { bCommas = TRUE; } uiLength = printNumber( ui64Val, uiBase, bUpperCase, bCommas, cNumberBuffer); - if (uiWidth < uiLength) + if( uiWidth < uiLength) { uiWidth = uiLength; } - if (uiFlags & FLM_PRINTF_ZERO_FLAG) + if( uiFlags & FLM_PRINTF_ZERO_FLAG) { // Zero fill uiPrecision = uiWidth; } - else if (!(uiFlags & FLM_PRINTF_MINUS_FLAG)) + else if( !(uiFlags & FLM_PRINTF_MINUS_FLAG)) { // Right justify - while (uiWidth > uiLength && uiWidth > uiPrecision) + while( uiWidth > uiLength && uiWidth > uiPrecision) { - outputChar( ' '); + m_iBytesOutput += m_pClient->outputChar( ' '); uiWidth--; } } // Handle the prefix (if any) - switch (uiPrefix) + switch( uiPrefix) { case FLM_PREFIX_NONE: break; case FLM_PREFIX_MINUS: - outputChar( '-'); + m_iBytesOutput += m_pClient->outputChar( '-'); break; case FLM_PREFIX_PLUS: - outputChar( '+'); + m_iBytesOutput += m_pClient->outputChar( '+'); break; case FLM_PREFIX_POUND: { - outputStr( "0x", 2); + m_iBytesOutput += m_pClient->outputStr( "0x", 2); break; } @@ -663,36 +719,37 @@ void F_Printf::numberFormatter( // Handle the precision - if (bCommas && uiPrecision && (uiPrecision % 4) == 0) + if( bCommas && uiPrecision && (uiPrecision % 4) == 0) { uiPrecision--; } - while (uiLength < uiPrecision) + while( uiLength < uiPrecision) { - if (bCommas && (uiPrecision % 4) == 0) + if( bCommas && (uiPrecision % 4) == 0) { - outputChar( ','); + m_iBytesOutput += m_pClient->outputChar( ','); uiPrecision--; uiWidth--; continue; } - outputChar( '0'); + m_iBytesOutput += m_pClient->outputChar( '0'); uiPrecision--; uiWidth--; } // Output the number - outputStr( cNumberBuffer, uiLength); + m_iBytesOutput += m_pClient->outputStr( cNumberBuffer, uiLength); - if (uiFlags & FLM_PRINTF_MINUS_FLAG) + if( uiFlags & FLM_PRINTF_MINUS_FLAG) { // Left justify - if (uiWidth > uiLength) + + if( uiWidth > uiLength) { - memsetChar( ' ', (uiWidth - uiLength)); + m_iBytesOutput += m_pClient->outputChar( ' ', (uiWidth - uiLength)); } } } @@ -712,7 +769,7 @@ void F_Printf::charFormatter( char cChar = (char)((cFormatChar == '%') ? (char)'%' : (char)f_va_arg( *args, int)); - outputChar( cChar); + m_iBytesOutput += m_pClient->outputChar( cChar); } /**************************************************************************** @@ -732,119 +789,74 @@ Desc: Unknown format handler void F_Printf::notHandledFormatter( void) { f_assert( 0); - outputChar( '?'); -} - -/**************************************************************************** -Desc: FLAIM's vsprintf -****************************************************************************/ -FLMINT FLMAPI F_Printf::strvPrintf( - char * pszDestStr, - const char * pszFormat, - f_va_list * args) -{ - m_pszDestStr = pszDestStr; - m_pLogMsg = NULL; - parseArgs( pszFormat, args); - *m_pszDestStr = 0; - - return( (FLMINT)(m_pszDestStr - pszDestStr)); + m_iBytesOutput += m_pClient->outputChar( '?'); } /**************************************************************************** Desc: ****************************************************************************/ -FLMINT FLMAPI F_Printf::strPrintf( - char * pszDestStr, - const char * pszFormat, +FLMINT FLMAPI f_printf( + IF_PrintfClient * pClient, + const char * pszFormat, ...) { f_va_list args; + FLMINT iBytesOutput; + F_Printf printFormatter( pClient); - m_pszDestStr = pszDestStr; - m_pLogMsg = NULL; - f_va_start(args, pszFormat); - parseArgs( pszFormat, &args); - f_va_end(args); - *m_pszDestStr = 0; + f_va_start( args, pszFormat); + iBytesOutput = printFormatter.parseArgs( pszFormat, &args); + f_va_end( args); - return( (FLMINT)(m_pszDestStr - pszDestStr)); + return( iBytesOutput); } /**************************************************************************** Desc: ****************************************************************************/ -FLMINT FLMAPI F_Printf::logvPrintf( - IF_LogMessageClient * pLogMsg, - const char * pszFormat, - f_va_list * args) +FLMINT FLMAPI f_vprintf( + IF_PrintfClient * pClient, + const char * pszFormat, + f_va_list * args) { - m_pszDestStr = NULL; - m_uiNumLogChars = 0; - m_uiCharOffset = 0; - m_pLogMsg = pLogMsg; - m_eCurrentForeColor = FLM_LIGHTGRAY; - m_eCurrentBackColor = FLM_BLACK; - m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); - parseArgs( pszFormat, args); - outputLogBuffer(); - - return( (FLMINT)m_uiNumLogChars); + F_Printf printFormatter( pClient); + + return( printFormatter.parseArgs( pszFormat, args)); } - + /**************************************************************************** Desc: ****************************************************************************/ -FLMINT FLMAPI F_Printf::logPrintf( - IF_LogMessageClient * pLogMsg, - const char * pszFormat, - ...) -{ - f_va_list args; - - m_pszDestStr = NULL; - m_uiNumLogChars = 0; - m_uiCharOffset = 0; - m_pLogMsg = pLogMsg; - m_eCurrentForeColor = FLM_BLACK; - m_eCurrentBackColor = FLM_LIGHTGRAY; - m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor); - f_va_start(args, pszFormat); - parseArgs( pszFormat, &args); - f_va_end(args); - outputLogBuffer(); - - return( m_uiNumLogChars); -} - -/**************************************************************************** -Desc: FLAIM's vsprintf -****************************************************************************/ FLMINT FLMAPI f_vsprintf( - char * pszDestStr, + char * pszDestBuffer, const char * pszFormat, f_va_list * args) { - F_Printf formatter; + FLMINT iLen; + F_BufferPrintfClient printfClient( pszDestBuffer); - return( formatter.strvPrintf( pszDestStr, pszFormat, args)); + iLen = f_vprintf( &printfClient, pszFormat, args); + printfClient.outputChar( 0); + + return( iLen); } /**************************************************************************** Desc: ****************************************************************************/ FLMINT FLMAPI f_sprintf( - char * pszDestStr, + char * pszDestBuffer, const char * pszFormat, ...) { - FLMINT iLen; - f_va_list args; - F_Printf formatter; + FLMINT iLen; + f_va_list args; + F_BufferPrintfClient printfClient( pszDestBuffer); - f_va_start(args, pszFormat); - iLen = formatter.strvPrintf( pszDestStr, pszFormat, &args); - f_va_end(args); + f_va_start( args, pszFormat); + iLen = f_vprintf( &printfClient, pszFormat, &args); + f_va_end( args); + printfClient.outputChar( 0); return( iLen); } @@ -856,17 +868,17 @@ FLMINT FLMAPI f_printf( const char * pszFormat, ...) { - FLMINT iLen; - f_va_list args; - char szTmpBuf[ 512]; - F_Printf formatter; + FLMINT iLen; + f_va_list args; + F_DynaPrintfClient printfClient; f_va_start( args, pszFormat); - iLen = formatter.strvPrintf( szTmpBuf, pszFormat, &args); - f_va_end(args); + iLen = f_vprintf( &printfClient, pszFormat, &args); + f_va_end( args); + printfClient.outputChar( 0); #ifndef FLM_RING_ZERO_NLM - fprintf( stdout, szTmpBuf); + fprintf( stdout, printfClient.getBufferPtr()); fflush( stdout); #endif diff --git a/ftk/src/ftkstrm.cpp b/ftk/src/ftkstrm.cpp index df9f7aa..ef8469f 100644 --- a/ftk/src/ftkstrm.cpp +++ b/ftk/src/ftkstrm.cpp @@ -97,6 +97,131 @@ FLMBYTE gv_ucBase64EncodeTable[ 64] = ASCII_EIGHT, ASCII_NINE, ASCII_PLUS, ASCII_SLASH }; +/*************************************************************************** +Desc: +***************************************************************************/ +class FLMEXP F_StreamPrintfClient : public IF_PrintfClient +{ +public: + + F_StreamPrintfClient( IF_OStream * pOStream) + { + m_pOStream = pOStream; + m_pOStream->AddRef(); + m_rc = NE_FLM_OK; + m_uiBufOffset = 0; + } + + virtual ~F_StreamPrintfClient() + { + if( m_pOStream) + { + m_pOStream->Release(); + m_pOStream = NULL; + } + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar, + FLMUINT uiCount) + { + FLMUINT uiTmpCount; + FLMINT iBytesOutput = (FLMINT)uiCount; + + while( uiCount) + { + uiTmpCount = uiCount; + + if( m_uiBufOffset + uiTmpCount > sizeof( m_szOutBuf)) + { + uiTmpCount = sizeof( m_szOutBuf) - m_uiBufOffset; + } + + f_memset( &m_szOutBuf[ m_uiBufOffset], cChar, uiTmpCount); + + m_uiBufOffset += uiTmpCount; + uiCount -= uiTmpCount; + + if( m_uiBufOffset == sizeof( m_szOutBuf)) + { + flushBuffer(); + } + } + + return( iBytesOutput); + } + + FINLINE FLMINT FLMAPI outputChar( + char cChar) + { + m_szOutBuf[ m_uiBufOffset++] = cChar; + + if( m_uiBufOffset == sizeof( m_szOutBuf)) + { + flushBuffer(); + } + + return( 1); + } + + FINLINE FLMINT FLMAPI outputStr( + const char * pszStr, + FLMUINT uiLen) + { + FLMUINT uiTmpLen; + FLMINT iBytesOutput = (FLMINT)uiLen; + + while( uiLen) + { + uiTmpLen = uiLen; + + if( m_uiBufOffset + uiTmpLen > sizeof( m_szOutBuf)) + { + uiTmpLen = sizeof( m_szOutBuf) - m_uiBufOffset; + } + + f_memcpy( &m_szOutBuf[ m_uiBufOffset], pszStr, uiTmpLen); + + m_uiBufOffset += uiTmpLen; + uiLen -= uiTmpLen; + pszStr += uiTmpLen; + + if( m_uiBufOffset == sizeof( m_szOutBuf)) + { + flushBuffer(); + } + } + + return( iBytesOutput); + } + + FINLINE FLMINT FLMAPI colorFormatter( + char, // cFormatChar, + eColorType, // eColor, + FLMUINT) // uiFlags) + { + return( 0); + } + + FINLINE RCODE flushBuffer( void) + { + if( RC_OK( m_rc) && m_uiBufOffset) + { + m_rc = m_pOStream->write( m_szOutBuf, m_uiBufOffset, NULL); + } + + m_uiBufOffset = 0; + return( m_rc); + } + +private: + + RCODE m_rc; + char m_szOutBuf[ 256]; + FLMUINT m_uiBufOffset; + IF_OStream * m_pOStream; +}; + /**************************************************************************** Desc: ****************************************************************************/ @@ -112,7 +237,7 @@ public: virtual ~F_TCPStream( void); - RCODE openConnection( + RCODE openStream( const char * pucHostAddress, FLMUINT uiPort, FLMUINT uiConnectTimeout = 3, @@ -203,6 +328,60 @@ private: unsigned long m_ulRemoteAddr; }; +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_OPENSSL +class F_SSLIOStream : public IF_SSLIOStream +{ +public: + + F_SSLIOStream() + { + m_pBio = NULL; + m_pContext = NULL; + m_pSSL = NULL; + m_pPeerCertificate = NULL; + m_pszPeerCertText = NULL; + m_szPeerName[ 0] = 0; + } + + virtual ~F_SSLIOStream() + { + closeStream(); + } + + RCODE FLMAPI openStream( + const char * pszTrustStore, + const char * pszHost, + FLMUINT uiPort = 443, + FLMUINT uiFlags = 0); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead = NULL); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten = NULL); + + const char * FLMAPI getPeerCertificateText( void); + + RCODE FLMAPI closeStream( void); + +private: + + BIO * m_pBio; + SSL_CTX * m_pContext; + SSL * m_pSSL; + X509 * m_pPeerCertificate; + char * m_pszPeerCertText; + char m_szPeerName[ 256]; +}; +#endif + /***************************************************************************** Desc: ******************************************************************************/ @@ -633,6 +812,81 @@ Exit: return( rc); } +/***************************************************************************** +Desc: +******************************************************************************/ +RCODE FLMAPI FlmAllocSSLIOStream( + IF_IOStream ** ppIOStream) +{ +#ifdef FLM_OPENSSL + + if( (*ppIOStream = f_new F_SSLIOStream) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); + +#else + + F_UNREFERENCED_PARM( ppIOStream); + return( RC_SET( NE_FLM_NOT_IMPLEMENTED)); + +#endif +} + +/***************************************************************************** +Desc: +******************************************************************************/ +RCODE FLMAPI FlmOpenSSLIOStream( + const char * pszTrustStore, + const char * pszHost, + FLMUINT uiPort, + FLMUINT uiFlags, + IF_IOStream ** ppIOStream) +{ +#ifdef FLM_OPENSSL + + RCODE rc = NE_FLM_OK; + F_SSLIOStream * pIOStream = NULL; + + if( (pIOStream = f_new F_SSLIOStream) == NULL) + { + rc = RC_SET( NE_FLM_MEM); + goto Exit; + } + + if( RC_BAD( rc = pIOStream->openStream( pszTrustStore, pszHost, + uiPort, uiFlags))) + { + goto Exit; + } + + *ppIOStream = pIOStream; + pIOStream = NULL; + +Exit: + + if( pIOStream) + { + pIOStream->Release(); + } + + return( rc); + +#else + + F_UNREFERENCED_PARM( pszTrustStore); + F_UNREFERENCED_PARM( pszHost); + F_UNREFERENCED_PARM( uiPort); + F_UNREFERENCED_PARM( uiFlags); + F_UNREFERENCED_PARM( ppIOStream); + + return( RC_SET( NE_FLM_NOT_IMPLEMENTED)); + +#endif +} + /**************************************************************************** Desc: *****************************************************************************/ @@ -2710,7 +2964,7 @@ F_TCPStream::~F_TCPStream( void) /******************************************************************** Desc: Opens a new connection *********************************************************************/ -RCODE F_TCPStream::openConnection( +RCODE F_TCPStream::openStream( const char * pucHostName, FLMUINT uiPort, FLMUINT uiConnectTimeout, @@ -3316,6 +3570,287 @@ Exit: return( NE_FLM_OK); } +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_OPENSSL +RCODE FLMAPI F_SSLIOStream::openStream( + const char * pszTrustStore, + const char * pszHost, + FLMUINT uiPort, + FLMUINT uiFlags) +{ + RCODE rc = NE_FLM_OK; + char szPort[ 32]; + X509_NAME * pPeerName; + EVP_PKEY * pPublicKey = NULL; + BIO * pMemBIO = NULL; + FLMUINT uiCertTextLen; + const char * pszCertText; + + if( !uiPort) + { + uiPort = 443; + } + + // Setup the connection to use SSLv2, SSLv3, or TLSv1 depending on + // the capabilities of the peer + + if( (m_pContext = SSL_CTX_new( SSLv23_client_method())) == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( pszTrustStore) + { + if( !SSL_CTX_load_verify_locations( m_pContext, pszTrustStore, NULL)) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + } + + if( (m_pBio = BIO_new_ssl_connect( m_pContext)) == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + BIO_get_ssl( m_pBio, &m_pSSL); + if( m_pSSL == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + SSL_set_mode( m_pSSL, SSL_MODE_AUTO_RETRY); + BIO_set_conn_hostname( m_pBio, pszHost); + + f_sprintf( szPort, "%u", (unsigned)uiPort); + BIO_set_conn_port( m_pBio, szPort); + + if( BIO_do_connect( m_pBio) <= 0) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( SSL_get_verify_result( m_pSSL) != X509_V_OK) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( (m_pPeerCertificate = SSL_get_peer_certificate( m_pSSL)) == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( (pPeerName = X509_get_subject_name( m_pPeerCertificate)) == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( (X509_NAME_get_text_by_NID( pPeerName, NID_commonName, + m_szPeerName, sizeof( m_szPeerName))) == -1) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( f_stricmp( pszHost, m_szPeerName) != 0) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + // Get the peer's certificate text + + if( (pMemBIO = BIO_new( BIO_s_mem())) == NULL) + { + rc = RC_SET( NE_FLM_MEM); + goto Exit; + } + + if( (pPublicKey = X509_get_pubkey( m_pPeerCertificate)) == NULL) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( pPublicKey->type != EVP_PKEY_RSA) + { + rc = RC_SET( NE_FLM_CONNECT_FAIL); + goto Exit; + } + + if( (PEM_write_bio_X509( pMemBIO, m_pPeerCertificate)) == 0) + { + rc = RC_SET( NE_FLM_MEM); + goto Exit; + } + + if( (uiCertTextLen = BIO_get_mem_data( pMemBIO, &pszCertText)) == 0) + { + rc = RC_SET( NE_FLM_MEM); + goto Exit; + } + + if( RC_BAD( rc = f_alloc( uiCertTextLen + 1, &m_pszPeerCertText))) + { + goto Exit; + } + + f_memcpy( m_pszPeerCertText, pszCertText, uiCertTextLen + 1); + +Exit: + + if( pMemBIO) + { + BIO_free( pMemBIO); + } + + if( pPublicKey) + { + EVP_PKEY_free( pPublicKey); + } + + if( RC_BAD( rc)) + { + closeStream(); + } + + return( rc); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_OPENSSL +RCODE FLMAPI F_SSLIOStream::read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead) +{ + RCODE rc = NE_FLM_OK; + int iBytesRead; + FLMUINT uiTotalBytesRead = 0; + char * pucBuffer = (char *)pvBuffer; + + while( uiBytesToRead) + { + if( (iBytesRead = BIO_read( m_pBio, &pucBuffer[ uiTotalBytesRead], + uiBytesToRead)) <= 0) + { + if( !BIO_should_retry( m_pBio)) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + + continue; + } + + uiTotalBytesRead += iBytesRead; + uiBytesToRead -= iBytesRead; + } + +Exit: + + if( puiBytesRead) + { + *puiBytesRead = uiTotalBytesRead; + } + + return( rc); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_OPENSSL +RCODE FLMAPI F_SSLIOStream::write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten) +{ + RCODE rc = NE_FLM_OK; + int iBytesWritten = 0; + + if( !uiBytesToWrite) + { + goto Exit; + } + + if( (iBytesWritten = BIO_write( m_pBio, pvBuffer, uiBytesToWrite)) <= 0) + { + iBytesWritten = 0; + rc = RC_SET( NE_FLM_SOCKET_WRITE_FAIL); + goto Exit; + } + +Exit: + + if( puiBytesWritten) + { + *puiBytesWritten = (FLMUINT)iBytesWritten; + } + + return( rc); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_OPENSSL +RCODE FLMAPI F_SSLIOStream::closeStream( void) +{ + if( m_pBio) + { + BIO_free_all( m_pBio); + m_pBio = NULL; + m_pSSL = NULL; + } + + if( m_pPeerCertificate) + { + X509_free( m_pPeerCertificate); + m_pPeerCertificate = NULL; + } + + if( m_pszPeerCertText) + { + f_free( &m_pszPeerCertText); + } + + if( m_pContext) + { + SSL_CTX_free( m_pContext); + m_pContext = NULL; + } + + m_szPeerName[ 0] = 0; + + return( NE_FLM_OK); +} +#endif + +/****************************************************************************** +Desc: +******************************************************************************/ +#ifdef FLM_OPENSSL +const char * FLMAPI F_SSLIOStream::getPeerCertificateText( void) +{ + return( m_pszPeerCertText); +} +#endif + /****************************************************************************** Desc: Read all data from input stream and write to the output stream. ******************************************************************************/ @@ -3408,3 +3943,89 @@ Exit: return( rc); } +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FlmReadLine( + IF_IStream * pIStream, + F_DynaBuf * pBuffer) +{ + RCODE rc = NE_FLM_OK; + char ucTmpBuf[ 32]; + + pBuffer->truncateData( 0); + + for( ;;) + { + if( RC_BAD( rc = pIStream->read( ucTmpBuf, 1, NULL))) + { + goto Exit; + } + + if( ucTmpBuf[ 0] != ASCII_CR) + { + if( RC_BAD( rc = pBuffer->appendByte( ucTmpBuf[ 0]))) + { + goto Exit; + } + } + else + { + if( RC_BAD( rc = pIStream->read( ucTmpBuf, 1, NULL))) + { + goto Exit; + } + + if( ucTmpBuf[ 0] != ASCII_LF) + { + rc = RC_SET( NE_FLM_SYNTAX); + goto Exit; + } + + break; + } + } + +Exit: + + if( pBuffer->getDataLength()) + { + if( RC_BAD( rc = pBuffer->appendByte( 0))) + { + goto Exit; + } + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_printf( + IF_OStream * pOStream, + const char * pszFormatStr, ...) +{ + f_va_list args; + F_StreamPrintfClient printfClient( pOStream); + + f_va_start( args, pszFormatStr); + f_vprintf( &printfClient, pszFormatStr, &args); + f_va_end( args); + return( printfClient.flushBuffer()); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_vprintf( + IF_OStream * pOStream, + const char * pszFormatStr, + f_va_list * args) +{ + F_StreamPrintfClient printfClient( pOStream); + + f_vprintf( &printfClient, pszFormatStr, args); + return( printfClient.flushBuffer()); +} + diff --git a/ftk/src/ftksys.h b/ftk/src/ftksys.h index 97014ec..597e003 100644 --- a/ftk/src/ftksys.h +++ b/ftk/src/ftksys.h @@ -183,6 +183,12 @@ #define INVALID_SOCKET -1 #endif + + #ifdef FLM_OPENSSL + #include + #include + #include + #endif #if defined( __va_copy) #define f_va_copy(to, from) __va_copy(to, from) @@ -308,6 +314,80 @@ #define F_DEFAULT_CBDATA_SLOTS 16 + /**************************************************************************** + Desc: + ****************************************************************************/ + class F_Printf : public F_Object + { + public: + + F_Printf( IF_PrintfClient * pClient) + { + m_pClient = pClient; + m_pClient->AddRef(); + m_iBytesOutput = 0; + } + + virtual ~F_Printf() + { + if( m_pClient) + { + m_pClient->Release(); + m_pClient = NULL; + } + } + + void processFieldInfo( + const char ** ppszFormat, + FLMUINT * puiWidth, + FLMUINT * puiPrecision, + FLMUINT * puiFlags, + f_va_list * args); + + void stringFormatter( + char cFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args); + + void charFormatter( + char cFormatChar, + f_va_list * args); + + void errorFormatter( + f_va_list * args); + + void notHandledFormatter( void); + + void numberFormatter( + char cFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args); + + FLMINT parseArgs( + const char * pszFormat, + f_va_list * args); + + void processFormatString( + FLMUINT uiLen, + ...); + + FLMUINT printNumber( + FLMUINT64 ui64Val, + FLMUINT uiBase, + FLMBOOL bUpperCase, + FLMBOOL bCommas, + char * pszBuf); + + private: + + IF_PrintfClient * m_pClient; + FLMINT m_iBytesOutput; + }; + /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/nlm_entrypoint.cpp b/ftk/src/nlm_entrypoint.cpp deleted file mode 100644 index 2dc2530..0000000 --- a/ftk/src/nlm_entrypoint.cpp +++ /dev/null @@ -1,476 +0,0 @@ -//------------------------------------------------------------------------- -// Desc: Entry point for Netware utilities -// Tabs: 3 -// -// Copyright (c) 2006-2007 Novell, Inc. All Rights Reserved. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version 2.1 -// of the License. -// -// This library 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 -// Library Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, contact Novell, Inc. -// -// To contact Novell about this file by physical or electronic mail, -// you may find current contact information at www.novell.com. -// -// $Id$ -//------------------------------------------------------------------------- - -#include "ftksys.h" -#include "ftknlm.h" - -#if defined( FLM_NLM) - -#if defined( FLM_RING_ZERO_NLM) - -static SEMAPHORE gv_lFlmSyncSem = 0; -static FLMBOOL gv_bUnloadCalled = FALSE; -static FLMBOOL gv_bMainRunning = FALSE; -static F_EXIT_FUNC gv_fnExit = NULL; - -// Variables defined in ftknlm.cpp - -extern FLMATOMIC gv_NetWareStartupCount; -extern void * gv_MyModuleHandle; -extern rtag_t gv_lAllocRTag; - -RCODE f_nssInitialize( void); - -void f_nssUninitialize( void); - -extern "C" int nlm_main( - int iArgC, - char ** ppszArgV); - -#endif - -/******************************************************************** -Desc: Startup routine for the NLM - that gets the main going in - its own thread. -*********************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -extern "C" void * f_nlmMainStub( - void * hThread, - void * pData) -{ - ARG_DATA * pArgData = (ARG_DATA *)pData; - struct LoadDefinitionStructure * moduleHandle = pArgData->moduleHandle; - - (void)hThread; - - (void)kSetThreadName( (void *)kCurrentThread(), - (BYTE *)pArgData->pszThreadName); - - nlm_main( pArgData->iArgC, pArgData->ppszArgV); - - Free( pArgData->ppszArgV); - Free( pArgData->pszArgs); - Free( pArgData->pszThreadName); - Free( pArgData); - - gv_bMainRunning = FALSE; - - if( !gv_bUnloadCalled) - { - KillMe( moduleHandle); - } - - kExitThread( NULL); - return( NULL); -} -#endif - -/******************************************************************** -Desc: Signals the f_nlmEntryPoint thread to release the console. -*********************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -void SynchronizeStart( void) -{ - if (gv_lFlmSyncSem) - { - (void)kSemaphoreSignal( gv_lFlmSyncSem); - } -} -#endif - -/******************************************************************** -Desc: Startup routine for the NLM. -*********************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -extern "C" LONG f_nlmEntryPoint( - struct LoadDefinitionStructure * moduleHandle, - struct ScreenStruct * initScreen, - char * commandLine, - char * loadDirectoryPath, - LONG uninitializedDataLength, - LONG fileHandle, - LONG (*ReadRoutine) - (LONG handle, - LONG offset, - char * buffer, - LONG length), - LONG customDataOffset, - LONG customDataSize) -{ - char * pszTmp; - char * pszArgStart; - int iArgC; - int iTotalArgChars; - int iArgSize; - char ** ppszArgV = NULL; - char * pszArgs = NULL; - char * pszDestArg; - bool bFirstPass = true; - char cEnd; - ARG_DATA * pArgData = NULL; - LONG sdRet = 0; - char * pszThreadName; - char * pszModuleName; - int iModuleNameLen; - int iThreadNameLen; - int iLoadDirPathSize; - void * hThread = NULL; - - (void)initScreen; - (void)uninitializedDataLength; - (void)fileHandle; - (void)ReadRoutine; - (void)customDataOffset; - (void)customDataSize; - - if( f_atomicInc( &gv_NetWareStartupCount) != 1) - { - goto Exit; - } - - gv_MyModuleHandle = moduleHandle; - gv_bUnloadCalled = FALSE; - - // Allocate the needed resource tags - - if( (gv_lAllocRTag = AllocateResourceTag( gv_MyModuleHandle, - "FLAIM Memory", AllocSignature)) == NULL) - { - sdRet = 1; - goto Exit; - } - - // Syncronized start - - if (moduleHandle->LDFlags & 4) - { - gv_lFlmSyncSem = kSemaphoreAlloc( (BYTE *)"FLAIM_SYNC", 0); - } - - // Initialize NSS - - if( RC_BAD( f_nssInitialize())) - { - sdRet = 1; - goto Exit; - } - - pszModuleName = (char *)(&moduleHandle->LDFileName[ 1]); - iModuleNameLen = (int)(moduleHandle->LDFileName[ 0]); - - // First pass: Count the arguments in the command line - // and determine how big of a buffer we will need. - // Second pass: Put argments into allocated buffer. - -Parse_Args: - - iTotalArgChars = 0; - iArgC = 0; - - iLoadDirPathSize = f_strlen( (const char *)loadDirectoryPath); - iArgSize = iLoadDirPathSize + iModuleNameLen; - - if( !bFirstPass) - { - ppszArgV[ iArgC] = pszDestArg; - f_memcpy( pszDestArg, loadDirectoryPath, iLoadDirPathSize); - f_memcpy( &pszDestArg[ iLoadDirPathSize], pszModuleName, iModuleNameLen); - pszDestArg[ iArgSize] = 0; - pszDestArg += (iArgSize + 1); - } - - iArgC++; - iTotalArgChars += iArgSize; - pszTmp = commandLine; - - for (;;) - { - // Skip leading blanks. - - while( *pszTmp && *pszTmp == ' ') - { - pszTmp++; - } - - if( *pszTmp == 0) - { - break; - } - - if( *pszTmp == '"' || *pszTmp == '\'') - { - cEnd = *pszTmp; - pszTmp++; - } - else - { - cEnd = ' '; - } - - pszArgStart = pszTmp; - iArgSize = 0; - - // Count the characters in the parameter. - - while( *pszTmp && *pszTmp != cEnd) - { - iArgSize++; - pszTmp++; - } - - if( !iArgSize && cEnd == ' ') - { - break; - } - - // If 2nd pass, save the argument. - - if( !bFirstPass) - { - ppszArgV[ iArgC] = pszDestArg; - - if( iArgSize) - { - f_memcpy( pszDestArg, pszArgStart, iArgSize); - } - - pszDestArg[ iArgSize] = 0; - pszDestArg += (iArgSize + 1); - } - - iArgC++; - iTotalArgChars += iArgSize; - - // Skip trailing quote or blank. - - if( *pszTmp) - { - pszTmp++; - } - } - - if( bFirstPass) - { - if ((ppszArgV = (char **)Alloc( sizeof( char *) * iArgC, - gv_lAllocRTag)) == NULL) - { - sdRet = 1; - goto Exit; - } - - if( (pszArgs = (char *)Alloc( iTotalArgChars + iArgC, - gv_lAllocRTag)) == NULL) - { - sdRet = 1; - goto Exit; - } - - pszDestArg = pszArgs; - bFirstPass = false; - goto Parse_Args; - } - - iThreadNameLen = (int)(moduleHandle->LDName[ 0]); - - if( (pszThreadName = (char *)Alloc( iThreadNameLen + 1, gv_lAllocRTag)) == NULL) - { - sdRet = 1; - goto Exit; - } - - f_memcpy( pszThreadName, (char *)(&moduleHandle->LDName[ 1]), iThreadNameLen); - pszThreadName[ iThreadNameLen] = 0; - - if( (pArgData = (ARG_DATA *)Alloc( sizeof( ARG_DATA), - gv_lAllocRTag)) == NULL) - { - sdRet = 1; - goto Exit; - } - - pArgData->ppszArgV = ppszArgV; - pArgData->pszArgs = pszArgs; - pArgData->iArgC = iArgC; - pArgData->moduleHandle = moduleHandle; - pArgData->pszThreadName = pszThreadName; - - gv_bMainRunning = TRUE; - - if( (hThread = kCreateThread( (BYTE *)"FTK main", - f_nlmMainStub, NULL, 32768, (void *)pArgData)) == NULL) - { - gv_bMainRunning = FALSE; - sdRet = 2; - goto Exit; - } - - if( kSetThreadLoadHandle( hThread, (LONG)moduleHandle) != 0) - { - (void)kDestroyThread( hThread); - gv_bMainRunning = FALSE; - sdRet = 2; - goto Exit; - } - - if( kScheduleThread( hThread) != 0) - { - (void)kDestroyThread( hThread); - gv_bMainRunning = FALSE; - sdRet = 2; - goto Exit; - } - - // Synchronized start - - if( moduleHandle->LDFlags & 4) - { - (void)kSemaphoreWait( gv_lFlmSyncSem); - } - -Exit: - - if( sdRet != 0) - { - f_atomicDec( &gv_NetWareStartupCount); - - if( ppszArgV) - { - Free( ppszArgV); - } - - if( pszArgs) - { - Free( pszArgs); - } - - if( pszThreadName) - { - Free( pszThreadName); - } - - if( pArgData) - { - Free( pArgData); - } - - if( gv_lFlmSyncSem) - { - kSemaphoreFree( gv_lFlmSyncSem); - gv_lFlmSyncSem = 0; - } - - if( !gv_bUnloadCalled) - { - KillMe( moduleHandle); - } - } - - return( sdRet); -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -extern "C" void f_nlmExitPoint(void) -{ - if( f_atomicDec( &gv_NetWareStartupCount) > 0) - { - return; - } - - gv_bUnloadCalled = TRUE; - - if( gv_fnExit) - { - (*gv_fnExit)(); - gv_fnExit = NULL; - } - - while( gv_bMainRunning) - { - kYieldThread(); - } - - f_nssUninitialize(); - - if( gv_lFlmSyncSem) - { - kSemaphoreFree( gv_lFlmSyncSem); - gv_lFlmSyncSem = 0; - } - - if( gv_lAllocRTag) - { - ReturnResourceTag( gv_lAllocRTag, 1); - gv_lAllocRTag = 0; - } -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -extern "C" void exit( - int exitCode) -{ - (void)exitCode; -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#if defined( FLM_RING_ZERO_NLM) -extern "C" int atexit( - F_EXIT_FUNC fnExit) -{ - gv_fnExit = fnExit; - return( 0); -} -#endif - -#endif // FLM_NLM - -/**************************************************************************** -Desc: -****************************************************************************/ -#if defined( FLM_OSX) -void gv_fnlm2() -{ -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#if !defined( FLM_NLM) -int ftknlmDummy2( void) -{ - return( 0); -} -#endif