//------------------------------------------------------------------------------ // Desc: Command-line environment for FLAIM utilities // // Tabs: 3 // // Copyright (c) 1999-2006 Novell, Inc. All Rights Reserved. // // This program is free software; you can redistribute it and/or // modify it under the terms of version 2 of the GNU General Public // License as published by the Free Software Foundation. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; 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: fshell.cpp 3133 2006-01-25 12:00:01 -0700 (Wed, 25 Jan 2006) dsanders $ //------------------------------------------------------------------------------ #include "fshell.h" #include "domedit.h" #ifdef FLM_UNIX #include #endif #ifdef FLM_WIN #include #endif // Imported global variables. extern FLMBOOL gv_bShutdown; // XML Import Error Handling #define flmErrorCodeEntry( c) { c, #c } #define MAX_IMPORT_ERROR_STRING 65 typedef struct { RCODE rc; const char * pszErrorStr; } XSHELL_ERROR_CODE_MAP; XSHELL_ERROR_CODE_MAP gv_XMLParseErrors[ XML_NUM_ERRORS - 1] = { flmErrorCodeEntry( XML_ERR_BAD_ELEMENT_NAME), flmErrorCodeEntry( XML_ERR_XMLNS_IN_ELEMENT_NAME), flmErrorCodeEntry( XML_ERR_ELEMENT_NAME_MISMATCH), flmErrorCodeEntry( XML_ERR_PREFIX_NOT_DEFINED), flmErrorCodeEntry( XML_ERR_EXPECTING_GT), flmErrorCodeEntry( XML_ERR_EXPECTING_ELEMENT_LT), flmErrorCodeEntry( XML_ERR_EXPECTING_EQ), flmErrorCodeEntry( XML_ERR_MULTIPLE_XMLNS_DECLS), flmErrorCodeEntry( XML_ERR_MULTIPLE_PREFIX_DECLS), flmErrorCodeEntry( XML_ERR_EXPECTING_QUEST_GT), flmErrorCodeEntry( XML_ERR_INVALID_XML_MARKUP), flmErrorCodeEntry( XML_ERR_MUST_HAVE_ONE_ATT_DEF), flmErrorCodeEntry( XML_ERR_EXPECTING_NDATA), flmErrorCodeEntry( XML_ERR_EXPECTING_SYSTEM_OR_PUBLIC), flmErrorCodeEntry( XML_ERR_EXPECTING_LPAREN), flmErrorCodeEntry( XML_ERR_EXPECTING_RPAREN_OR_PIPE), flmErrorCodeEntry( XML_ERR_EXPECTING_NAME), flmErrorCodeEntry( XML_ERR_INVALID_ATT_TYPE), flmErrorCodeEntry( XML_ERR_INVALID_DEFAULT_DECL), flmErrorCodeEntry( XML_ERR_EXPECTING_PCDATA), flmErrorCodeEntry( XML_ERR_EXPECTING_ASTERISK), flmErrorCodeEntry( XML_ERR_EMPTY_CONTENT_INVALID), flmErrorCodeEntry( XML_ERR_CANNOT_MIX_CHOICE_AND_SEQ), flmErrorCodeEntry( XML_ERR_XML_ILLEGAL_PI_NAME), flmErrorCodeEntry( XML_ERR_ILLEGAL_FIRST_NAME_CHAR), flmErrorCodeEntry( XML_ERR_ILLEGAL_COLON_IN_NAME), flmErrorCodeEntry( XML_ERR_EXPECTING_VERSION), flmErrorCodeEntry( XML_ERR_INVALID_VERSION_NUM), flmErrorCodeEntry( XML_ERR_UNSUPPORTED_ENCODING), flmErrorCodeEntry( XML_ERR_EXPECTING_YES_OR_NO), flmErrorCodeEntry( XML_ERR_EXPECTING_QUOTE_BEFORE_EOL), flmErrorCodeEntry( XML_ERR_EXPECTING_SEMI), flmErrorCodeEntry( XML_ERR_UNEXPECTED_EOL_IN_ENTITY), flmErrorCodeEntry( XML_ERR_INVALID_CHARACTER_NUMBER), flmErrorCodeEntry( XML_ERR_UNSUPPORTED_ENTITY), flmErrorCodeEntry( XML_ERR_EXPECTING_QUOTE), flmErrorCodeEntry( XML_ERR_INVALID_PUBLIC_ID_CHAR), flmErrorCodeEntry( XML_ERR_EXPECTING_WHITESPACE), flmErrorCodeEntry( XML_ERR_EXPECTING_HEX_DIGIT), flmErrorCodeEntry( XML_ERR_INVALID_BINARY_ATTR_VALUE), flmErrorCodeEntry( XML_ERR_CREATING_CDATA_NODE), flmErrorCodeEntry( XML_ERR_CREATING_COMMENT_NODE), flmErrorCodeEntry( XML_ERR_CREATING_PI_NODE), flmErrorCodeEntry( XML_ERR_CREATING_DATA_NODE), flmErrorCodeEntry( XML_ERR_CREATING_ROOT_ELEMENT), flmErrorCodeEntry( XML_ERR_CREATING_ELEMENT_NODE) }; #define FSMI_ENTRY_ELEMENT 2 #define FSMI_INTERNAL_ENTRY_FLAGS_ATTR 21 #define FSMI_ENTRY_MODIFY_TIME_ATTR 22 #define FSMI_ENTRY_FLAGS_ATTR 23 #define FSMI_PARTITION_ID_ATTR 24 #define FSMI_CLASS_ID_ATTR 25 #define FSMI_PARENT_ID_ATTR 26 #define FSMI_ALT_ID_ATTR 27 #define FSMI_SUBORDINATE_COUNT_ATTR 28 #define FSMI_RDN_ATTR 29 #define FSMI_FIRST_CHILD_ATTR 30 #define FSMI_LAST_CHILD_ATTR 31 #define FSMI_NEXT_SIBLING_ATTR 32 #define FSMI_PREV_SIBLING_ATTR 33 #define FSMI_ATTR_GVTS_ATTR 50 #define FSMI_ATTR_DTS_ATTR 51 #define FSMI_VALUE_FLAGS_ATTR 52 #define FSMI_VALUE_MTS_ATTR 53 #define FSMI_TTL_ATTR 54 #define FSMI_POLICY_DN_ATTR 55 typedef struct OVERHEAD_INFO { FLMUINT64 ui64DOMOverhead; FLMUINT64 ui64ValueBytes; } OVERHEAD_INFO; typedef struct ATTR_NODE_INFO { FLMUINT uiAttrNameId; char * pszAttrName; FLMUINT64 ui64NumValues; OVERHEAD_INFO GVTS; OVERHEAD_INFO DTS; OVERHEAD_INFO ValueFlags; OVERHEAD_INFO ValueMTS; OVERHEAD_INFO TTL; OVERHEAD_INFO PolicyDN; OVERHEAD_INFO OtherNodes; } ATTR_NODE_INFO; class Entry_Info { public: Entry_Info(); ~Entry_Info(); FINLINE void resetOverheadInfo( OVERHEAD_INFO * pOverhead) { pOverhead->ui64DOMOverhead = 0; pOverhead->ui64ValueBytes = 0; } FINLINE void initAttrInfo( FLMUINT uiAttrNameId, ATTR_NODE_INFO * pAttrInfo) { pAttrInfo->uiAttrNameId = uiAttrNameId; pAttrInfo->pszAttrName = NULL; pAttrInfo->ui64NumValues = 0; resetOverheadInfo( &pAttrInfo->GVTS); resetOverheadInfo( &pAttrInfo->DTS); resetOverheadInfo( &pAttrInfo->ValueFlags); resetOverheadInfo( &pAttrInfo->ValueMTS); resetOverheadInfo( &pAttrInfo->TTL); resetOverheadInfo( &pAttrInfo->PolicyDN); resetOverheadInfo( &pAttrInfo->OtherNodes); } void getOverheadInfo( OVERHEAD_INFO * pOverhead); RCODE getXMLAttrInfo( IF_Db * pDb, IF_DOMNode * pNode, OVERHEAD_INFO * pOverhead, FLMUINT uiAttrNameId); RCODE getAttrValueInfo( IF_Db * pDb, IF_DOMNode * pValueNode, ATTR_NODE_INFO * pAttrNodeInfo); RCODE processAttrValues( IF_Db * pDb, IF_DOMNode * pAttrNode, ATTR_NODE_INFO * pAttrNodeInfo); FLMBOOL findDirAttr( FLMUINT uiAttrNameId, FLMUINT * puiInsertPos); RCODE getDirAttrInfo( IF_Db * pDb, IF_DOMNode * pAttrNode); RCODE processEntryAttrs( IF_Db * pDb, IF_DOMNode * pEntryNode); RCODE addEntryInfo( IF_Db * pDb, IF_DOMNode * pEntryNode); FLMUINT64 m_ui64NumEntries; FLMUINT64 m_ui64TotalBytes; OVERHEAD_INFO m_EntryNode; OVERHEAD_INFO m_AttrNode; OVERHEAD_INFO m_InternalEntryFlags; OVERHEAD_INFO m_ModifyTime; OVERHEAD_INFO m_EntryFlags; OVERHEAD_INFO m_PartitionID; OVERHEAD_INFO m_ClassID; OVERHEAD_INFO m_ParentID; OVERHEAD_INFO m_AlternateID; OVERHEAD_INFO m_SubordinateCount; OVERHEAD_INFO m_RDN; OVERHEAD_INFO m_FirstChild; OVERHEAD_INFO m_LastChild; OVERHEAD_INFO m_NextSibling; OVERHEAD_INFO m_PrevSibling; ATTR_NODE_INFO * m_pAttrList; FLMUINT m_uiAttrListSize; FLMUINT m_uiNumAttrs; F_NodeInfo m_nodeInfo; F_Pool m_pool; }; // Local prototypes RCODE flmBackupProgFunc( FLMUINT uiStatusType, void * Parm1, void * Parm2, void * UserData); FLMINT fshellFileSystemTest( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell); FSTATIC void format64BitNum( FLMUINT64 ui64Num, char * pszBuf, FLMBOOL bOutputHex, FLMBOOL bAddCommas = FALSE); RCODE flmXmlImportStatus( eXMLStatus eStatusType, void * pvArg1, void * pvArg2, void * pvArg3, void * pvUserData); RCODE importXmlFiles( IF_Db * pDb, FLMUINT uiCollection, FlmShell * pShell, char * pszPath, XFLM_IMPORT_STATS * pImportStats); RCODE getErrFromFile( IF_PosIStream * pFileIStream, FLMUINT uiCurrLineFilePos, FLMUINT uiCurrLineBytes, XMLEncoding eXMLEncoding, char * pszErrorString); FSTATIC void domDisplayError( FTX_WINDOW * pWindow, const char * pszError, RCODE errRc); FSTATIC void domOutputValues( FTX_WINDOW * pWindow, FLMUINT * puiLineCount, IF_FileHdl * pFileHdl, const char * pszLabel, FLMUINT64 ui64Bytes, FLMUINT uiPercent, FLMUINT64 ui64Count); FSTATIC void domDisplayLine( FTX_WINDOW * pWindow, FLMUINT * puiLineCount, IF_FileHdl * pFileHdl, const char * pszLine, const char * pszWaitPrompt = NULL); FSTATIC void domDisplayValue( FTX_WINDOW * pWindow, FLMUINT * puiLineCount, IF_FileHdl * pFileHdl, const char * pszLabel, FLMUINT uiPercent, FLMUINT64 ui64Value); FSTATIC void domDisplayInfo( FTX_WINDOW * pWindow, FLMUINT * puiLineCount, IF_FileHdl * pFileHdl, const char * pszDomOverheadLabel, const char * pszValueBytesLabel, OVERHEAD_INFO * pInfo, FLMUINT64 ui64TotalBytes); const char * errorToString( XMLParseError errorType); /**************************************************************************** Desc: *****************************************************************************/ class F_LocalRestore : public F_FSRestore { public: ~F_LocalRestore() {} F_LocalRestore() { } FINLINE RCODE setup( char * pszDbPath, char * pszBackupSetPath, char * pszRflDir) { return( F_FSRestore::setup( pszDbPath, pszBackupSetPath, pszRflDir)); } FINLINE RCODE FLMAPI openRflFile( FLMUINT uiFileNum) { return( F_FSRestore::openRflFile( uiFileNum)); } FINLINE RCODE FLMAPI read( FLMUINT uiLength, void * pvBuffer, FLMUINT * puiBytesRead) { return( F_FSRestore::read( uiLength, pvBuffer, puiBytesRead)); } private: }; /**************************************************************************** Desc: *****************************************************************************/ class F_LocalRestoreStatus : public F_DefaultRestoreStatus { public: F_LocalRestoreStatus( FlmShell * pShell) { m_pShell = pShell; m_bFirstStatus = TRUE; m_uiTransCount = 0; m_uiAddCount = 0; m_uiDeleteCount = 0; m_uiModifyCount = 0; m_uiReserveCount = 0; m_uiIndexCount = 0; m_uiRflFileNum = 0; m_ui64RflBytesRead = 0; } RCODE FLMAPI reportProgress( eRestoreAction * peAction, FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone); RCODE FLMAPI reportError( eRestoreAction * peAction, RCODE rcErr); RCODE FLMAPI reportBeginTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId); RCODE FLMAPI reportCommitTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId); RCODE FLMAPI reportAbortTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId); RCODE FLMAPI reportOpenRflFile( eRestoreAction * peAction, FLMUINT uiFileNum) { m_uiRflFileNum = uiFileNum; updateCountDisplay(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportRflRead( eRestoreAction * peAction, FLMUINT uiFileNum, FLMUINT uiBytesRead) { (void)uiFileNum; m_ui64RflBytesRead += uiBytesRead; *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportBlockChainFree( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT64, // ui64MaintDocNum, FLMUINT, // uiStartBlkAddr, FLMUINT, // uiEndBlkAddr, FLMUINT // uiCount ) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportEnableEncryption( eRestoreAction * peAction, FLMUINT64 ui64TransId); RCODE FLMAPI reportWrapKey( eRestoreAction * peAction, FLMUINT64 ui64TransId); RCODE FLMAPI reportRollOverDbKey( eRestoreAction * peAction, FLMUINT64) // ui64TransId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportDocumentDone( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64) // ui64NodeId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeCreate( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64RefNodeId, eDomNodeType, // eNodeType, FLMUINT, // uiNameId, eNodeInsertLoc) // eLocation) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeDelete( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64) // ui64NodeId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeChildrenDelete( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64NodeId, FLMUINT) // uiNameId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportInsertBefore( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64ParentId, FLMUINT64, // ui64NewChildId, FLMUINT64) // ui64RefChildId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeUpdate( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64) // ui64NodeId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeSetValue( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64) // ui64NodeId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeFlagsUpdate( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64NodeId, FLMUINT, // uiFlags, FLMBOOL) // bAdd) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeSetPrefixId( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64NodeId, FLMUINT) // uiPrefixId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportSetNextNodeId( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64) // ui64NextNodeId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeSetMetaValue( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64NodeId, FLMUINT64 // ui64MetaValue ) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportAttributeDelete( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64ElementId, FLMUINT) // uiAttrName) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportAttributeSetValue( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64ElementId, FLMUINT) // uiNameId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } RCODE FLMAPI reportNodeSetPrefixId( eRestoreAction * peAction, FLMUINT64, // ui64TransId, FLMUINT, // uiCollection, FLMUINT64, // ui64NodeId, FLMUINT, // uiAttrName, FLMUINT) // uiPrefixId) { *peAction = XFLM_RESTORE_ACTION_CONTINUE; return( NE_XFLM_OK); } private: RCODE report_preamble( FTX_WINDOW * pWin); RCODE report_postamble( FTX_WINDOW * pWin); void updateCountDisplay( void); FlmShell * m_pShell; FLMBOOL m_bFirstStatus; FLMUINT m_uiTransCount; FLMUINT m_uiAddCount; FLMUINT m_uiDeleteCount; FLMUINT m_uiModifyCount; FLMUINT m_uiReserveCount; FLMUINT m_uiIndexCount; FLMUINT m_uiRflFileNum; FLMUINT64 m_ui64RflBytesRead; }; /**************************************************************************** Desc: *****************************************************************************/ class F_LocalBackupClient : public F_DefaultBackupClient { public: F_LocalBackupClient( FlmShell * pShell, char * pszBackupPath) : F_DefaultBackupClient( pszBackupPath) { m_pShell = pShell; } private: FlmShell * m_pShell; }; /**************************************************************************** Desc: *****************************************************************************/ class F_LocalBackupStatus : public IF_BackupStatus { public: F_LocalBackupStatus( FlmShell * pShell) { m_pShell = pShell; } RCODE FLMAPI backupStatus( FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone); FINLINE FLMINT FLMAPI getRefCount( void) { return( IF_BackupStatus::getRefCount()); } virtual FINLINE FLMINT FLMAPI AddRef( void) { return( IF_BackupStatus::AddRef()); } virtual FINLINE FLMINT FLMAPI Release( void) { return( IF_BackupStatus::Release()); } private: FlmShell * m_pShell; }; /**************************************************************************** Desc: *****************************************************************************/ FlmShell::FlmShell( void) : FlmThreadContext() { m_histPool.poolInit( 512); m_argPool.poolInit( 512); f_memset( m_DbList, 0, MAX_SHELL_OPEN_DB * sizeof( IF_Db *)); m_pTitleWin = NULL; m_iCurrArgC = 0; m_ppCurrArgV = NULL; m_iLastCmdExitCode = 0; m_bPagingEnabled = FALSE; m_pSharedContext = NULL; f_memset( m_ppCmdList, 0, sizeof( FlmCommand *) * MAX_REGISTERED_COMMANDS); f_memset( m_ppHistory, 0, sizeof( char *) * MAX_SHELL_HISTORY_ITEMS); } /**************************************************************************** Desc: *****************************************************************************/ FlmShell::~FlmShell( void) { FLMUINT uiLoop; m_histPool.poolFree(); m_argPool.poolFree(); // Free the command objects. for( uiLoop = 0; uiLoop < MAX_REGISTERED_COMMANDS; uiLoop++) { if( m_ppCmdList[ uiLoop] != NULL) { m_ppCmdList[ uiLoop]->Release(); } } // Free the history items for( uiLoop = 0; uiLoop < MAX_SHELL_HISTORY_ITEMS; uiLoop++) { if( m_ppHistory[ uiLoop]) { f_free( &m_ppHistory[ uiLoop]); } } // Close all open databases for( uiLoop = 0; uiLoop < MAX_SHELL_OPEN_DB; uiLoop++) { if( m_DbList[ uiLoop]) { m_DbList[ uiLoop]->Release(); } } } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::setup( FlmSharedContext * pSharedContext) { FlmCommand * pCommand = NULL; RCODE rc = NE_XFLM_OK; flmAssert( pSharedContext != NULL); m_pSharedContext = pSharedContext; if( RC_BAD( rc = FlmThreadContext::setup( m_pSharedContext, "X-FLAIM Shell", NULL, NULL))) { goto Exit; } // Register dbopen command if( (pCommand = f_new FlmDbOpenCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register dbclose command if( (pCommand = f_new FlmDbCloseCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register dbcopy, dbrename, and dbremove command handler if( (pCommand = f_new FlmDbManageCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register trans command if( (pCommand = f_new FlmTransCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register backup command if( (pCommand = f_new FlmBackupCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register restore command if( (pCommand = f_new FlmRestoreCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register database config command if( (pCommand = f_new FlmDbConfigCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register database get config command if( (pCommand = f_new FlmDbGetConfigCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register sysinfo command if( (pCommand = f_new FlmSysInfoCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the hex conversion command if( (pCommand = f_new FlmHexConvertCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the base64 conversion command if( (pCommand = f_new FlmBase64ConvertCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the file delete command if( (pCommand = f_new FlmFileSysCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the import command if( (pCommand = f_new FlmImportCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the dom edit command if( (pCommand = f_new FlmDomEditCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the export command if( (pCommand = f_new FlmExportCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the wrap key command if( (pCommand = f_new FlmWrapKeyCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register nodeinfo command if( (pCommand = f_new FlmNodeInfoCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register btreeinfo command if( (pCommand = f_new FlmBTreeInfoCommand) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; Exit: if( pCommand) { pCommand->Release(); } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::registerDatabase( IF_Db * pDb, FLMUINT * puiDbId) { FLMUINT uiLoop; RCODE rc = NE_XFLM_OK; *puiDbId = 0xFFFFFFFF; for( uiLoop = 0; uiLoop < MAX_SHELL_OPEN_DB; uiLoop++) { if( !m_DbList[ uiLoop]) { m_DbList[ uiLoop] = pDb; *puiDbId = uiLoop; break; } } if( *puiDbId == 0xFFFFFFFF) { rc = RC_SET( NE_XFLM_TOO_MANY_OPEN_DATABASES); goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::getDatabase( FLMUINT uiDbId, IF_Db ** ppDb) { RCODE rc = NE_XFLM_OK; if( uiDbId >= MAX_SHELL_OPEN_DB) { rc = RC_SET( NE_XFLM_FAILURE); goto Exit; } *ppDb = m_DbList[ uiDbId]; Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::deregisterDatabase( FLMUINT uiDbId) { RCODE rc = NE_XFLM_OK; if( uiDbId >= MAX_SHELL_OPEN_DB) { rc = RC_SET( NE_XFLM_FAILURE); goto Exit; } m_DbList[ uiDbId] = NULL; Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::con_printf( const char * pszFormat, ...) { char szBuffer[ 512]; f_va_list args; if( m_pWindow) { f_va_start( args, pszFormat); f_vsprintf( szBuffer, pszFormat, &args); f_va_end( args); FTXWinPrintStr( m_pWindow, szBuffer); } return( NE_XFLM_OK); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::parseCmdLine( char * pszString) { FLMUINT uiArgCount = 0; FLMUINT uiCurrToken = 0; FLMUINT uiTokenLen; char * pszCurrToken; FLMBOOL bQuoted; FlmParse Parser; RCODE rc = NE_XFLM_OK; m_argPool.poolReset( NULL); m_iCurrArgC = 0; m_ppCurrArgV = NULL; m_pszOutputFile = NULL; Parser.setString( pszString); while( Parser.getNextToken()) { uiArgCount++; } if (RC_BAD( rc = m_argPool.poolCalloc( uiArgCount * sizeof( char *), (void **)&m_ppCurrArgV))) { goto Exit; } uiCurrToken = 0; Parser.setString( pszString); while( (pszCurrToken = Parser.getNextToken()) != NULL) { bQuoted = FALSE; if( *pszCurrToken == '\"') { // Skip the quote character pszCurrToken++; bQuoted = TRUE; } uiTokenLen = f_strlen( pszCurrToken); if (!bQuoted && uiTokenLen >= 2 && *pszCurrToken == '>' && !m_pszOutputFile) { if (RC_BAD( rc = m_argPool.poolCalloc( uiTokenLen, (void **)&m_pszOutputFile))) { goto Exit; } f_strcpy( m_pszOutputFile, pszCurrToken + 1); } else { if (RC_BAD( rc = m_argPool.poolCalloc( uiTokenLen + 1, (void **)&m_ppCurrArgV [uiCurrToken]))) { goto Exit; } f_strcpy( m_ppCurrArgV[ uiCurrToken], pszCurrToken); if( bQuoted) { // Strip off the trailing quote m_ppCurrArgV[ uiCurrToken][ uiTokenLen - 1] = '\0'; } uiCurrToken++; } } m_iCurrArgC = (FLMINT)uiCurrToken; Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::executeCmdLine( void) { RCODE rc = NE_XFLM_OK; FLMBOOL bValidCommand = FALSE; FLMUINT uiLoop; IF_BufferIStream * pBufIStream = NULL; if( !m_iCurrArgC) { goto Exit; } // Process internal commands if( f_stricmp( m_ppCurrArgV[ 0], "cls") == 0) { FTXWinClear( m_pWindow); bValidCommand = TRUE; } else if( f_stricmp( m_ppCurrArgV[ 0], "exit") == 0) { setShutdownFlag(); bValidCommand = TRUE; } #if defined (FLM_NLM) else if( f_stricmp( m_ppCurrArgV[ 0], "realpath") == 0) { bValidCommand = TRUE; char newPath[ 256]; int err = 0; if( m_iCurrArgC !=2) { con_printf( "Wrong Number Of Params\n"); } else { if( !realpath( m_ppCurrArgV[ 1], newPath)) { con_printf("Error getting real path"); } else { con_printf( "%s\n", newPath); } } } #endif else if( f_stricmp( m_ppCurrArgV[ 0], "echo") == 0) { FLMBOOL bNewline = FALSE; if( m_iCurrArgC > 1 && f_stricmp( m_ppCurrArgV[ 1], "-n") == 0) { bNewline = TRUE; uiLoop = 2; } else { uiLoop = 1; } for( ; uiLoop < (FLMUINT)m_iCurrArgC; uiLoop++) { con_printf( "%s", (char *)m_ppCurrArgV[ uiLoop]); } if( bNewline) { con_printf( "\n"); } bValidCommand = TRUE; } else if( f_stricmp( m_ppCurrArgV[ 0], "shell") == 0) { FlmShell * pTmpShell; if( (pTmpShell = f_new FlmShell) != NULL) { if( RC_BAD( pTmpShell->setup( m_pSharedContext))) { pTmpShell->Release(); } else { m_pSharedContext->spawn( pTmpShell); } } bValidCommand = TRUE; } else if( f_stricmp( m_ppCurrArgV[ 0], "qp") == 0) { F_XPath xpathObj; F_Query query; RCODE tmpRc; bValidCommand = TRUE; if( m_iCurrArgC != 3) { con_printf( "Invalid number of arguments.\n\n"); } else { FLMUINT uiDbId; F_Db * pDb; uiDbId = f_atol( m_ppCurrArgV[ 1]); if( RC_BAD( rc = getDatabase( uiDbId, (IF_Db **)&pDb))) { con_printf( "Invalid database ID.\n\n"); goto Exit; } if( !pBufIStream) { if( RC_BAD( rc = FlmAllocBufferIStream( &pBufIStream))) { goto Exit; } } pBufIStream->open( m_ppCurrArgV[ 2], f_strlen( m_ppCurrArgV[ 2])); tmpRc = xpathObj.parseQuery( pDb, pBufIStream, &query); pBufIStream->close(); con_printf( "Result: 0x%08X\n\n", (unsigned)tmpRc); } } else if( f_stricmp( m_ppCurrArgV[ 0], "meta") == 0) { FLMUINT uiMeta; FLMUINT uiAltMeta; bValidCommand = TRUE; if( m_iCurrArgC != 2) { con_printf( "Invalid number of arguments.\n\n"); } else { if( !pBufIStream) { if( RC_BAD( rc = FlmAllocBufferIStream( &pBufIStream))) { goto MetaExit; } } pBufIStream->open( m_ppCurrArgV[ 1], f_strlen( m_ppCurrArgV[ 1])); for( ;;) { RCODE tmpRc; if( RC_BAD( tmpRc = f_getNextMetaphone( pBufIStream, &uiMeta, &uiAltMeta))) { if( tmpRc != NE_XFLM_EOF_HIT) { con_printf( "Error: 0x%04X\n", tmpRc); } break; } con_printf( "Meta = 0x%04X, AltMeta = 0x%04X\n", uiMeta, uiAltMeta); } MetaExit: if( pBufIStream) { pBufIStream->close(); } } } else if( f_stricmp( m_ppCurrArgV[ 0], "help") == 0 || f_stricmp( m_ppCurrArgV[ 0], "?") == 0 || f_stricmp( m_ppCurrArgV[ 0], "h") == 0) { if( m_iCurrArgC < 2) { con_printf( "Commands:\n"); displayCommand( "help, ?, h", "Show help"); displayCommand( "shell", "Start a new shell"); displayCommand( "echo", "Echo typed in command"); displayCommand( "cls", "Clear screen"); displayCommand( "exit", "Exit shell"); displayCommand( "echo", "Echo typed in command"); for( uiLoop = 0; uiLoop < MAX_REGISTERED_COMMANDS; uiLoop++) { if( m_ppCmdList[ uiLoop] != NULL) { m_ppCmdList[ uiLoop]->displayHelp( this, NULL); } } } else { for( uiLoop = 0; uiLoop < MAX_REGISTERED_COMMANDS; uiLoop++) { if( m_ppCmdList[ uiLoop] != NULL) { if (m_ppCmdList[ uiLoop]->canPerformCommand( (char *)m_ppCurrArgV [1])) { m_ppCmdList[ uiLoop]->displayHelp( this, (char *)m_ppCurrArgV [1]); break; } } } } bValidCommand = TRUE; } else { for( uiLoop = 0; uiLoop < MAX_REGISTERED_COMMANDS; uiLoop++) { if( m_ppCmdList[ uiLoop] != NULL) { if( m_ppCmdList[ uiLoop]->canPerformCommand( (char *)m_ppCurrArgV[ 0])) { m_ppCmdList[ uiLoop]->execute( m_iCurrArgC, m_ppCurrArgV, this); bValidCommand = TRUE; break; } } } } if( !bValidCommand) { FTXWinPrintf( m_pWindow, "Unrecognized command: %s\n", m_ppCurrArgV[ 0]); rc = RC_SET( NE_XFLM_NOT_IMPLEMENTED); goto Exit; } Exit: if( pBufIStream) { pBufIStream->Release(); } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::registerCmd( FlmCommand * pCmd) { RCODE rc = NE_XFLM_OK; FLMBOOL bRegistered = FALSE; FLMUINT uiLoop; for( uiLoop = 0; uiLoop < MAX_REGISTERED_COMMANDS; uiLoop++) { if( m_ppCmdList[ uiLoop] == NULL) { m_ppCmdList[ uiLoop] = pCmd; bRegistered = TRUE; break; } } if( !bRegistered) { rc = RC_SET( NE_XFLM_FAILURE); goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::addCmdHistory( char * pszCmd) { FLMUINT uiLoop; FLMUINT uiSlot; FLMUINT uiCmdLen; RCODE rc = NE_XFLM_OK; // If the command line is too long, don't store it in the // history buffer if( (uiCmdLen = f_strlen( pszCmd)) > MAX_CMD_LINE_LEN) { goto Exit; } // Look for a duplicate history item for( uiLoop = 0; uiLoop < MAX_SHELL_HISTORY_ITEMS; uiLoop++) { if( m_ppHistory[ uiLoop] && f_strcmp( pszCmd, m_ppHistory[ uiLoop]) == 0) { // Remove the command from the history list and compress // the history table f_free( &m_ppHistory[ uiLoop]); if( uiLoop < MAX_SHELL_HISTORY_ITEMS - 1) { f_memmove( &m_ppHistory[ uiLoop], &m_ppHistory[ uiLoop + 1], sizeof( char *) * (MAX_SHELL_HISTORY_ITEMS - uiLoop - 1)); m_ppHistory[ MAX_SHELL_HISTORY_ITEMS - 1] = NULL; break; } } } // Find an empty slot for the new history item for( uiSlot = MAX_SHELL_HISTORY_ITEMS; uiSlot > 0; uiSlot--) { if( m_ppHistory[ uiSlot - 1]) { break; } } if( uiSlot == MAX_SHELL_HISTORY_ITEMS) { f_free( &m_ppHistory[ 0]); f_memmove( &m_ppHistory[ 0], &m_ppHistory[ 1], sizeof( char *) * (MAX_SHELL_HISTORY_ITEMS - 1)); m_ppHistory[ MAX_SHELL_HISTORY_ITEMS - 1] = NULL; uiSlot = MAX_SHELL_HISTORY_ITEMS - 1; } if( RC_BAD( rc = f_alloc( uiCmdLen + 1, &m_ppHistory[ uiSlot]))) { goto Exit; } f_strcpy( m_ppHistory[ uiSlot], pszCmd); Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::execute( void) { char szBuffer[ MAX_CMD_LINE_LEN + 1]; char szThreadName[ MAX_THREAD_NAME_LEN + 1]; FLMUINT uiTermChar; FLMUINT uiRow; FLMUINT uiLastHistorySlot = MAX_SHELL_HISTORY_ITEMS; RCODE rc = NE_XFLM_OK; char szDir [F_PATH_MAX_SIZE]; DirectoryIterator directoryIterator; char * pszTabCompleteBegin = NULL; IF_PosIStream * pFileIStream = NULL; if( RC_BAD( rc = FTXScreenInit( "xshell main", &m_pScreen))) { goto Exit; } if( RC_BAD( rc = FTXScreenInitStandardWindows( m_pScreen, FLM_RED, FLM_WHITE, FLM_BLUE, FLM_WHITE, FALSE, FALSE, NULL, &m_pTitleWin, &m_pWindow))) { goto Exit; } FTXScreenDisplay( m_pScreen); FTXScreenSetShutdownFlag( m_pScreen, getShutdownFlagAddr()); szBuffer[ 0] = '\0'; for( ;;) { // Refresh the title bar getName( szThreadName); FTXWinSetCursorPos( m_pTitleWin, 0, 0); FTXWinPrintf( m_pTitleWin, "%5.5u: %s", (unsigned)getID(), szThreadName); FTXWinClearToEOL( m_pTitleWin); // Check for shutdown if( getShutdownFlag()) { break; } FTXWinGetCursorPos( m_pWindow, NULL, &uiRow); FTXWinSetCursorPos( m_pWindow, 0, uiRow); FTXWinClearToEOL( m_pWindow); #if defined( FLM_NLM) szDir [0] = 0; #elif defined( FLM_WIN) if (_getcwd( (char *)szDir, F_PATH_MAX_SIZE) == NULL) { szDir [0] = '\0'; } #elif defined( FLM_UNIX) if (getcwd( (char *)szDir, F_PATH_MAX_SIZE) == NULL) { szDir [0] = '\0'; } #else #error "This platform is not supported" #endif FTXWinPrintf( m_pWindow, "%s>", szDir); if( FTXLineEdit( m_pWindow, szBuffer, MAX_CMD_LINE_LEN, 255, 0, &uiTermChar)) { break; } if( uiTermChar == FKB_TAB) { char szBase[ 255]; char szWildcard[ 255]; szWildcard[0] = '\0'; pszTabCompleteBegin = positionToPath( szBuffer); if ( f_strchr( pszTabCompleteBegin, '\"')) { // remove quotes removeChars( pszTabCompleteBegin, '\"'); } // If we have not initialized our iterator to scan this directory // or if the command-line does not contain a path that we provided // we need to reinitialize the iterator. if( !directoryIterator.isInitialized() || !pszTabCompleteBegin || !directoryIterator.isInSet( pszTabCompleteBegin)) { extractBaseDirAndWildcard( pszTabCompleteBegin, szBase, szWildcard); directoryIterator.reset(); directoryIterator.setupForSearch( szDir, szBase, szWildcard); } if ( !directoryIterator.isEmpty()) { // Copy in the next entry along with its full path. directoryIterator.next( pszTabCompleteBegin, TRUE); } else { FTXBeep(); } // If the completed path contains spaces, quote it if ( f_strchr( pszTabCompleteBegin, ASCII_SPACE)) { f_memmove( pszTabCompleteBegin + 1, pszTabCompleteBegin, f_strlen( pszTabCompleteBegin) + 1); pszTabCompleteBegin[0] = '\"'; f_strcat( pszTabCompleteBegin, "\""); } continue; } directoryIterator.reset(); if( uiTermChar == FKB_UP) { for(; uiLastHistorySlot > 0; uiLastHistorySlot--) { if( m_ppHistory[ uiLastHistorySlot - 1]) { f_strcpy( szBuffer, m_ppHistory[ uiLastHistorySlot - 1]); uiLastHistorySlot--; break; } } continue; } if( uiTermChar == FKB_DOWN) { for(; uiLastHistorySlot < MAX_SHELL_HISTORY_ITEMS - 1; uiLastHistorySlot++) { if( m_ppHistory[ uiLastHistorySlot + 1]) { f_strcpy( szBuffer, m_ppHistory[ uiLastHistorySlot + 1]); uiLastHistorySlot++; break; } } continue; } if( uiTermChar == FKB_ESCAPE) { szBuffer[ 0] = '\0'; continue; } if( uiTermChar == FKB_F1) { FLMUINT uiLen; addCmdHistory( szBuffer); if( RC_BAD( rc = FlmOpenFileIStream( szBuffer, &pFileIStream))) { goto BatchError; } for( ;;) { FTXWinPrintf( m_pWindow, "\n"); uiLen = MAX_CMD_LINE_LEN; if( RC_BAD( rc = flmReadLine( pFileIStream, (FLMBYTE *)szBuffer, &uiLen))) { if( rc == NE_XFLM_EOF_HIT) { rc = NE_XFLM_OK; if( !uiLen) { break; } } goto BatchError; } parseCmdLine( szBuffer); szBuffer[ 0] = '\0'; if( RC_BAD( rc = executeCmdLine())) { goto BatchError; } } BatchError: if( RC_BAD( rc)) { FTXWinPrintf( m_pWindow, "Error: %e. Batch execution halted.\n", rc); rc = NE_XFLM_OK; } continue; } uiLastHistorySlot = MAX_SHELL_HISTORY_ITEMS; if( szBuffer [0]) { FTXWinPrintf( m_pWindow, "\n"); addCmdHistory( szBuffer); parseCmdLine( szBuffer); executeCmdLine(); szBuffer[0] = '\0'; continue; } FTXWinPrintf( m_pWindow, "\n"); } Exit: if( pFileIStream) { pFileIStream->Release(); } if( m_pWindow) { FTXWinFree( &m_pWindow); } if( m_pScreen) { FTXScreenFree( &m_pScreen); } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ FlmParse::FlmParse( void) { m_szString [0] = 0; m_pszCurPos = &m_szString [0]; } /**************************************************************************** Desc: *****************************************************************************/ void FlmParse::setString( char * pszString) { if( pszString) { f_strcpy( m_szString, pszString); } else { m_szString [0]= 0; } m_pszCurPos = &m_szString [0]; } /**************************************************************************** Desc: *****************************************************************************/ char * FlmParse::getNextToken( void) { char * pszTokenPos = &m_szToken [0]; FLMBOOL bQuoted = FALSE; while( *m_pszCurPos && *m_pszCurPos == ' ') { m_pszCurPos++; } if( *m_pszCurPos == '$') { *pszTokenPos++ = *m_pszCurPos++; while( *m_pszCurPos) { if( (*m_pszCurPos >= 'A' && *m_pszCurPos <= 'Z') || (*m_pszCurPos >= 'a' && *m_pszCurPos <= 'z') || (*m_pszCurPos >= '0' && *m_pszCurPos <= '9') || (*m_pszCurPos == '_')) { *pszTokenPos++ = *m_pszCurPos++; } else { break; } } } else if( *m_pszCurPos == '=') { *pszTokenPos++ = *m_pszCurPos++; } else { while( *m_pszCurPos && (*m_pszCurPos != ' ' || bQuoted)) { if( *m_pszCurPos == '\"') { *pszTokenPos++ = *m_pszCurPos++; if( bQuoted) { break; } else { bQuoted = TRUE; } } else { *pszTokenPos++ = *m_pszCurPos++; } } } *pszTokenPos = '\0'; if( m_szToken [0] == 0) { return( NULL); } return( &m_szToken [0]); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbOpenCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMINT iExitCode = 0; IF_Db * pDb = NULL; FLMUINT uiDbId; RCODE rc = NE_XFLM_OK; F_DbSystem dbSystem; char * pszRflDir = NULL; char * pszPassword = NULL; char * pszAllowLimited; FLMBOOL bAllowLimited = FALSE; if( iArgC < 2) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( iArgC >= 3) { pszRflDir = ppszArgV[ 2]; } if (iArgC >=4) { pszPassword = ppszArgV[ 3]; } if (iArgC >=5) { pszAllowLimited = ppszArgV[ 4]; if (f_strnicmp( pszAllowLimited, "TRUE", 4) == 0) { bAllowLimited = TRUE; } } if( RC_BAD( rc = dbSystem.dbOpen( ppszArgV[ 1], NULL, pszRflDir, pszPassword, bAllowLimited, &pDb))) { if( rc != NE_FLM_IO_PATH_NOT_FOUND) { goto Exit; } if( RC_BAD( rc = dbSystem.dbCreate( ppszArgV[ 1], NULL, pszRflDir, NULL, NULL, NULL, &pDb))) { goto Exit; } } if( RC_BAD( rc = pShell->registerDatabase( pDb, &uiDbId))) { goto Exit; } pDb = NULL; pShell->con_printf( "Database #%u opened.\n", (unsigned)uiDbId); Exit: if( pDb) { pDb->Release(); } if( RC_BAD( rc)) { pShell->con_printf( "Error opening database: %e\n", rc); iExitCode = -1; } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmDbOpenCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbopen", "Open a database"); } else { pShell->con_printf("Usage:\n" " dbopen [ [ []]]\n"); pShell->con_printf(" : TRUE | FALSE \n"); } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmDbOpenCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "dbopen", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbCloseCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMINT iExitCode = 0; FLMUINT uiDbId; IF_Db * pDb; RCODE rc = NE_XFLM_OK; F_DbSystem dbSystem; if( iArgC != 2) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( !f_stricmp( ppszArgV[ 1], "kill")) { dbSystem.deactivateOpenDb( NULL, NULL); pShell->con_printf( "All handles killed, but not necessarily closed.\n"); } else if( !f_stricmp( ppszArgV[ 1], "all")) { for( uiDbId = 0; uiDbId < MAX_SHELL_OPEN_DB; uiDbId++) { if( RC_BAD( rc = pShell->getDatabase( uiDbId, &pDb))) { goto Exit; } if( pDb) { if( RC_BAD( rc = pShell->deregisterDatabase( uiDbId))) { goto Exit; } pDb->Release(); pShell->con_printf( "Database #%u closed.\n", (unsigned)uiDbId); } } dbSystem.closeUnusedFiles( 0); } else { uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( rc = pShell->getDatabase( uiDbId, &pDb))) { goto Exit; } if( pDb) { if( RC_BAD( rc = pShell->deregisterDatabase( uiDbId))) { goto Exit; } pDb->Release(); pShell->con_printf( "Database #%u closed.\n", (unsigned)uiDbId); } else { pShell->con_printf( "Database #%u already closed.\n", (unsigned)uiDbId); } } Exit: if( RC_BAD( rc)) { pShell->con_printf( "Error closing database: %e\n", rc); iExitCode = -1; } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmDbCloseCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbclose", "Close a database"); } else { pShell->con_printf("Usage:\n" " dbclose \n"); } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmDbCloseCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "dbclose", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmTransCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMINT iExitCode = 0; FLMUINT uiDbId; FLMUINT uiTimeout; eDbTransType eTransType; IF_Db * pDb; RCODE rc = NE_XFLM_OK; if( iArgC < 2) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } // Get the database ID and handle uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( pShell->getDatabase( uiDbId, &pDb)) || !pDb) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } eTransType = ((F_Db *)pDb)->getTransType(); if( f_stricmp( ppszArgV [0], "trbegin") == 0) { if( iArgC < 3) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( eTransType != XFLM_NO_TRANS) { pShell->con_printf( "%s transaction is already active on database %u.\n", (char *)(eTransType == XFLM_READ_TRANS ? "A read" : "An update"), (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( !f_stricmp( ppszArgV[ 2], "read")) { if( RC_BAD( rc = pDb->transBegin( XFLM_READ_TRANS))) { goto Exit; } } else if( !f_stricmp( ppszArgV[ 2], "update")) { uiTimeout = 10; if( iArgC > 4) { uiTimeout = f_atol( ppszArgV[ 3]); } if( RC_BAD( rc = pDb->transBegin( XFLM_UPDATE_TRANS, uiTimeout))) { goto Exit; } } else { pShell->con_printf( "Invalid parameter: %s\n", ppszArgV[ 3]); iExitCode = -1; goto Exit; } pShell->con_printf( "Transaction on %u started.\n", (unsigned)uiDbId); } else if( f_stricmp( ppszArgV[ 0], "trcommit") == 0) { if( eTransType == XFLM_NO_TRANS) { pShell->con_printf( "There is no active transaction on database %u.\n", (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( RC_BAD( rc = pDb->transCommit())) { goto Exit; } pShell->con_printf( "Transaction committed on database %u.\n", (unsigned)uiDbId); } else if( f_stricmp( ppszArgV[ 0], "trabort") == 0) { if( eTransType == XFLM_NO_TRANS) { pShell->con_printf( "There is no active transaction on database %u.\n", (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( RC_BAD( rc = pDb->transAbort())) { goto Exit; } pShell->con_printf( "Transaction aborted on database %u.\n", (unsigned)uiDbId); } else { // should never be able to get here! flmAssert( 0); iExitCode = -1; goto Exit; } Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmTransCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "trbegin", "Begin a transaction"); pShell->displayCommand( "trcommit", "Commit a transaction"); pShell->displayCommand( "trabort", "Abort a transaction"); } else { pShell->con_printf("Usage:\n"); if (f_stricmp( pszCommand, "trbegin") == 0) { pShell->con_printf( " trbegin db# [read | update ]\n"); } else { pShell->con_printf( " %s db#\n", pszCommand); } } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmTransCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "trbegin", pszCommand) == 0 || f_stricmp( "trcommit", pszCommand) == 0 || f_stricmp( "trabort", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: Status class for reporting progress of database copy *****************************************************************************/ class FSHELL_CopyStatus : public IF_DbCopyStatus { public: FSHELL_CopyStatus( FlmShell * pShell) { m_pShell = pShell; m_pWin = m_pShell->getWindow(); } virtual ~FSHELL_CopyStatus() { } RCODE FLMAPI dbCopyStatus( FLMUINT64 ui64BytesToCopy, FLMUINT64 ui64BytesCopied, FLMBOOL bNewSrcFile, const char * pszSrcFileName, const char * pszDestFileName) { RCODE rc = NE_XFLM_OK; if (bNewSrcFile) { FTXWinPrintf( m_pWin, "\nCopying %s to %s ...\n", pszSrcFileName, pszDestFileName); } if( m_pShell->getShutdownFlag()) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } FTXWinPrintf( m_pWin, " %,I64u of %,I64u bytes copied\r", ui64BytesCopied, ui64BytesToCopy); f_yieldCPU(); #ifdef FLM_WIN f_sleep( 0); #endif if( RC_OK( FTXWinTestKB( m_pWin))) { FLMUINT uiChar; FTXWinInputChar( m_pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } } Exit: return( rc); } private: FlmShell * m_pShell; FTX_WINDOW * m_pWin; }; /**************************************************************************** Desc: Status class for reporting progress of database rename *****************************************************************************/ class FSHELL_RenameStatus : public IF_DbRenameStatus { public: FSHELL_RenameStatus( FlmShell * pShell) { m_pShell = pShell; } virtual ~FSHELL_RenameStatus() { } FINLINE RCODE FLMAPI dbRenameStatus( const char * pszSrcFileName, const char * pszDstFileName) { m_pShell->con_printf( "Renaming %s to %s ...\n", pszSrcFileName, pszDstFileName); return( NE_XFLM_OK); } private: FlmShell * m_pShell; }; /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbManageCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMINT iExitCode = 0; RCODE rc = NE_XFLM_OK; F_DbSystem dbSystem; if( iArgC < 2) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if (f_stricmp( ppszArgV [0], "dbremove") == 0) { if (RC_BAD( rc = dbSystem.dbRemove( ppszArgV[ 1], NULL, NULL, TRUE))) { goto Exit; } } else { if( iArgC < 3) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if (f_stricmp( ppszArgV [0], "dbcopy") == 0) { FSHELL_CopyStatus copyStatus( pShell); if (RC_BAD( rc = dbSystem.dbCopy( ppszArgV [1], NULL, NULL, ppszArgV [2], NULL, NULL, ©Status))) { goto Exit; } pShell->con_printf( "\n\n"); } else { FSHELL_RenameStatus renameStatus( pShell); if (RC_BAD( rc = dbSystem.dbRename( ppszArgV [1], NULL, NULL, ppszArgV [2], TRUE, &renameStatus))) { goto Exit; } pShell->con_printf( "\n\n"); } } Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmDbManageCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbcopy", "Copy a database"); pShell->displayCommand( "dbrename", "Rename a database"); pShell->displayCommand( "dbremove", "Delete a database"); } else { pShell->con_printf("Usage:\n"); if (f_stricmp( pszCommand, "dbremove") == 0) { pShell->con_printf( " dbremove \n"); } else { pShell->con_printf( " %s \n", pszCommand); } } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmDbManageCommand::canPerformCommand( char * pszCommand ) { return( (f_stricmp( "dbcopy", pszCommand) == 0 || f_stricmp( "dbrename", pszCommand) == 0 || f_stricmp( "dbremove", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmBackupCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMUINT uiDbId; FLMUINT uiIncSeqNum; IF_Db * pDb; IF_Backup * pBackup = NULL; IF_BackupClient * pBackupClient = NULL; IF_BackupStatus * pBackupStatus = NULL; FLMINT iExitCode = 0; eDbBackupType eBackupType = XFLM_FULL_BACKUP; RCODE rc = NE_XFLM_OK; FLMBOOL bUsePasswd = FALSE; if( iArgC < 3) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if (iArgC > 3) { bUsePasswd = TRUE; } if( iArgC > 4) { if( f_strnicmp( ppszArgV[ 3], "inc", 3) == 0) { eBackupType = XFLM_INCREMENTAL_BACKUP; } } // Get the database ID and handle uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( pShell->getDatabase( uiDbId, &pDb)) || !pDb) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } if( RC_BAD( rc = pDb->backupBegin( eBackupType, XFLM_READ_TRANS, 0, &pBackup))) { goto Exit; } if( (pBackupClient = f_new F_LocalBackupClient( pShell, ppszArgV[ 2])) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( (pBackupStatus = f_new F_LocalBackupStatus( pShell)) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = pBackup->backup( ppszArgV[ 2], bUsePasswd?ppszArgV[3]:NULL, pBackupClient, pBackupStatus, &uiIncSeqNum))) { goto Exit; } if( RC_BAD( rc = pBackup->endBackup())) { goto Exit; } pShell->con_printf( "\nBackup complete.\n"); Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } if( pBackup) { pBackup->Release(); } if( pBackupClient) { pBackupClient->Release(); } if( pBackupStatus) { pBackupStatus->Release(); } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmBackupCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbbackup", "Backup a database"); } else { pShell->con_printf("Usage:\n"); pShell->con_printf( " %s [ [\"INC\"]]\n", pszCommand); } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmBackupCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "dbbackup", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalBackupStatus::backupStatus( FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); if( m_pShell->getShutdownFlag()) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } FTXWinPrintf( pWin, "%,I64u / %,I64u bytes backed up\r", ui64BytesDone, ui64BytesToDo); f_yieldCPU(); #ifdef FLM_WIN f_sleep( 0); #endif if( pWin && RC_OK( FTXWinTestKB( pWin))) { FLMUINT uiChar; FTXWinInputChar( pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } } Exit: return( rc); } /************************************************************************ If we want status info for backups, we need to implement an IF_BackupClient..... RCODE flmBackupProgFunc( FLMUINT uiStatusType, void * Parm1, void * Parm2, void * UserData) { RCODE rc = NE_XFLM_OK; FLMUINT64 ui64BytesDone; FLMUINT64 ui64BytesToDo; FlmShell * pShell = (FlmShell *)UserData; FTX_WINDOW * pWin = pShell->getWindow(); F_UNREFERENCED_PARM( Parm2); F_UNREFERENCED_PARM( UserData); if( pShell->getShutdownFlag()) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } if( uiStatusType == FLM_DB_BACKUP_STATUS) { pDbBackupInfo = (DB_BACKUP_INFO *)Parm1; FTXWinPrintf( pWin, "%,I64u / %,I64u bytes backed up\r", ui64BytesDone, ui64BytesToDo); } f_yieldCPU(); if( pWin && FTXWinTestKB( pWin) == FTXRC_SUCCESS) { FLMUINT uiChar; FTXWinInputChar( pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } } Exit: return( rc); } ***********************************************************************/ /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmRestoreCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { char * pszRflDir = NULL; FLMINT iExitCode = 0; F_LocalRestore * pRestore = NULL; F_LocalRestoreStatus restoreStatus( pShell); RCODE rc = NE_XFLM_OK; F_DbSystem dbSystem; FLMBOOL bUsePasswd = FALSE; if( iArgC < 3) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( iArgC > 3) { bUsePasswd = TRUE; } if( iArgC > 4) { pszRflDir = ppszArgV[ 4]; } if( (pRestore = f_new F_LocalRestore) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if( RC_BAD( rc = pRestore->setup( ppszArgV[ 1], ppszArgV[ 2], pszRflDir))) { goto Exit; } if( RC_BAD( rc = dbSystem.dbRestore( ppszArgV[ 1], NULL, NULL, NULL, bUsePasswd?ppszArgV[3]:NULL, pRestore, &restoreStatus))) { goto Exit; } pShell->con_printf( "\nRestore complete.\n"); Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } if( pRestore) { pRestore->Release(); } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmRestoreCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbrestore", "Restore a database"); } else { pShell->con_printf("Usage:\n"); pShell->con_printf( " %s [ []]\n", pszCommand); } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmRestoreCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "dbrestore", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: The report* functions are all status callbacks that allow XFlaim to pass some information back out *****************************************************************************/ void F_LocalRestoreStatus::updateCountDisplay( void) { FTX_WINDOW * pWin = m_pShell->getWindow(); if (pWin) { FTXWinSetCursorPos( pWin, 0, 2); FTXWinPrintf( pWin, "RFLFile#: %-10u TotalCnt: %-10u RflKBytes: %uK\n" "AddCnt: %-10u DelCnt: %-10u ModCnt: %u\n" "TrCnt: %-10u RsrvCnt: %-10u IxSetCnt: %u", m_uiRflFileNum, m_uiTransCount + m_uiAddCount + m_uiDeleteCount + m_uiModifyCount + m_uiReserveCount + m_uiIndexCount, (unsigned)(m_ui64RflBytesRead / 1024), m_uiAddCount, m_uiDeleteCount, m_uiModifyCount, m_uiTransCount, m_uiReserveCount, m_uiIndexCount); } } // Contains some common code that all of the report* functions call after // their primary processing... RCODE F_LocalRestoreStatus::report_preamble( FTX_WINDOW * pWin) { RCODE rc = NE_XFLM_OK; if( m_pShell->getShutdownFlag()) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } if( m_bFirstStatus) { FTXWinClear( pWin); m_bFirstStatus = FALSE; } Exit: return rc; } // Contains some common code that all of the report* functions call after // their primary processing... RCODE F_LocalRestoreStatus::report_postamble( FTX_WINDOW * pWin) { RCODE rc = NE_XFLM_OK; FTXWinSetCursorPos( pWin, 0, 5); f_yieldCPU(); if( pWin && RC_OK( FTXWinTestKB( pWin))) { FLMUINT uiChar; FTXWinInputChar( pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( NE_XFLM_USER_ABORT); goto Exit; } } Exit: return rc; } RCODE F_LocalRestoreStatus::reportProgress( eRestoreAction * peAction, FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 1); FTXWinPrintf( pWin, "%,I64u / %,I64u bytes restored", ui64BytesDone, ui64BytesToDo); FTXWinClearToEOL( pWin); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportError( eRestoreAction * peAction, RCODE rcErr) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); FLMUINT uiChar; *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 6); FTXWinClearToEOL( pWin); FTXWinPrintf( pWin, "Error: 0x%04X. Retry (Y/N): ", (unsigned)rcErr); if( RC_BAD( FTXWinInputChar( pWin, &uiChar))) { uiChar = 0; goto Exit; } if( uiChar == 'Y' || uiChar == 'y') { *peAction = XFLM_RESTORE_ACTION_RETRY; } FTXWinClearToEOL( pWin); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportBeginTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 5); FTXWinPrintf( pWin, "BEGIN_TRANS: ID = 0x%I64X", ui64TransId); FTXWinClearToEOL( pWin); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportCommitTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 5); FTXWinPrintf( pWin, "COMMIT_TRANS: ID = 0x%I64X", ui64TransId); FTXWinClearToEOL( pWin); m_uiTransCount++; updateCountDisplay(); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportAbortTrans( eRestoreAction * peAction, FLMUINT64 ui64TransId) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 5); FTXWinPrintf( pWin, "ABORT_TRANS: ID = 0x%I64X", ui64TransId); FTXWinClearToEOL( pWin); m_uiTransCount++; updateCountDisplay(); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportEnableEncryption( eRestoreAction * peAction, FLMUINT64 ui64TransId) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 5); FTXWinPrintf( pWin, "ENABLE_ENCRYPTION: ID = 0x%I64X", ui64TransId); FTXWinClearToEOL( pWin); m_uiTransCount++; updateCountDisplay(); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } RCODE F_LocalRestoreStatus::reportWrapKey( eRestoreAction * peAction, FLMUINT64 ui64TransId) { RCODE rc = NE_XFLM_OK; FTX_WINDOW * pWin = m_pShell->getWindow(); *peAction = XFLM_RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble( pWin))) { goto Exit; } FTXWinSetCursorPos( pWin, 0, 5); FTXWinPrintf( pWin, "WRAP_KEY: ID = 0x%I64X", ui64TransId); FTXWinClearToEOL( pWin); m_uiTransCount++; updateCountDisplay(); if (RC_BAD(rc = report_postamble( pWin))) { goto Exit; } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbConfigCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMUINT uiDbId; IF_Db * pDb; FLMINT iExitCode = 0; RCODE rc = NE_XFLM_OK; if( iArgC < 3) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } // Get the database ID and handle uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( pShell->getDatabase( uiDbId, &pDb)) || !pDb) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } if( f_stricmp( ppszArgV[ 2], "rflkeepfiles") == 0) { FLMBOOL bEnable; if( iArgC < 4) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } if (f_stricmp( ppszArgV[ 3], "on") == 0) { bEnable = TRUE; } else if (f_stricmp( ppszArgV[ 3], "off") == 0) { bEnable = FALSE; } else { pShell->con_printf( "Invalid value, must be 'on' or 'off'.\n"); iExitCode = -1; goto Exit; } if( RC_BAD( rc = ((F_Db *)pDb)->setRflKeepFilesFlag( bEnable))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "rfldir") == 0) { if( iArgC < 4) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } if( RC_BAD( rc = ((F_Db *)pDb)->setRflDir( ppszArgV[ 3]))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "rflfilelimits") == 0) { FLMUINT uiRflMinSize; FLMUINT uiRflMaxSize; if( iArgC < 5) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } uiRflMinSize = f_atol( ppszArgV[ 3]); uiRflMaxSize = f_atol( ppszArgV[ 4]); if( RC_BAD( rc = ((F_Db *)pDb)->setRflFileSizeLimits( uiRflMinSize, uiRflMaxSize))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "rflrolltonextfile") == 0) { if( RC_BAD( rc = ((F_Db *)pDb)->rflRollToNextFile())) { goto Exit; } } else { pShell->con_printf( "Invalid option.\n"); iExitCode = -1; goto Exit; } Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmDbConfigCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbconfig", "Configure a database"); } else { pShell->con_printf("Usage:\n"); pShell->con_printf( " %s rflkeepfiles \n", pszCommand); pShell->con_printf( " %s rfldir \n", pszCommand); pShell->con_printf( " %s rflfilelimits \n", pszCommand); pShell->con_printf( " %s rolltonextfile\n", pszCommand); } } /**************************************************************************** Desc: *****************************************************************************/ FLMBOOL FlmDbConfigCommand::canPerformCommand( char * pszCommand) { return( (f_stricmp( "dbconfig", pszCommand) == 0) ? TRUE : FALSE); } /**************************************************************************** Desc: *****************************************************************************/ FSTATIC void format64BitNum( FLMUINT64 ui64Num, char * pszBuf, FLMBOOL bOutputHex, FLMBOOL bAddCommas ) { char szTmpBuf [60]; FLMUINT uiDigit; FLMUINT uiChars = 0; FLMUINT uiCharsBetweenCommas; if (bOutputHex) { while (ui64Num) { uiDigit = (FLMUINT)(ui64Num & 0xF); szTmpBuf [uiChars++] = (char)(uiDigit + '0'); ui64Num >>= 4; } } else { uiCharsBetweenCommas = 0; while (ui64Num) { if (bAddCommas && uiCharsBetweenCommas == 3) { szTmpBuf [uiChars++] = ','; uiCharsBetweenCommas = 0; } uiDigit = (FLMUINT)(ui64Num % 10); szTmpBuf [uiChars++] = (char)(uiDigit + '0'); ui64Num /= 10; uiCharsBetweenCommas++; } } // Need to reverse the numbers going back out. while (uiChars) { uiChars--; *pszBuf++ = szTmpBuf [uiChars]; } *pszBuf = 0; } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbGetConfigCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMUINT uiDbId; IF_Db * pIDb; F_Db * pDb; FLMINT iExitCode = 0; FLMUINT64 ui64Arg; FLMUINT uiArg; FLMUINT uiArg2; FLMBOOL bArg; char szTmpPath[ F_PATH_MAX_SIZE]; char ucBuf[ 256]; RCODE rc = NE_XFLM_OK; FLMBOOL bDoAll = FALSE; FLMBOOL bValidOption = FALSE; if( iArgC < 3) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } // Get the database ID and handle uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( pShell->getDatabase( uiDbId, &pIDb)) || !pIDb) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } pDb = (F_Db *)pIDb; if (f_stricmp( ppszArgV [2], "all") == 0) { bDoAll = TRUE; bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rfldir") == 0) { pDb->getRflDir( szTmpPath); pShell->con_printf( "RFL directory = %s\n", szTmpPath); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rflfilenum") == 0) { pDb->getRflFileNum( &uiArg); pShell->con_printf( "Current RFL file # = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rflsizelimits") == 0) { pDb->getRflFileSizeLimits( &uiArg, &uiArg2); pShell->con_printf( "RFL file size limits = min:%u, max:%u\n", (unsigned)uiArg, (unsigned)uiArg2); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "diskusage") == 0) { FLMUINT64 ui64DbSize; FLMUINT64 ui64RollbackSize; FLMUINT64 ui64RflSize; char szBuf1 [40]; char szBuf2 [40]; char szBuf3 [40]; if( RC_BAD( rc = pDb->getDiskSpaceUsage( &ui64DbSize, &ui64RollbackSize, &ui64RflSize))) { goto Exit; } format64BitNum( ui64DbSize, szBuf1, FALSE); format64BitNum( ui64RollbackSize, szBuf2, FALSE); format64BitNum( ui64RflSize, szBuf3, FALSE); pShell->con_printf( "Sizes = db:%s, rollback:%s, rfl:%s", szBuf1, szBuf2, szBuf3); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rflkeepfiles") == 0) { if( RC_BAD( rc = pDb->getRflKeepFlag( &bArg))) { goto Exit; } pShell->con_printf( "Keep RFL files = %s\n", bArg ? "Yes" : "No"); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "lastbackuptransid") == 0) { if( RC_BAD( rc = pDb->getLastBackupTransID( &ui64Arg))) { goto Exit; } //VISIT: Use formatter for 64 bit unsigned pShell->con_printf( "Last backup transaction ID = %u\n", (unsigned)ui64Arg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "blockschangedsincebackup") == 0) { if( RC_BAD( rc = pDb->getBlocksChangedSinceBackup( &uiArg))) { goto Exit; } pShell->con_printf( "Blocks changed since last backup = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "serialnumber") == 0) { pDb->getSerialNumber( ucBuf); pShell->con_printf( "Serial number = " "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", (unsigned)ucBuf[ 0], (unsigned)ucBuf[ 1], (unsigned)ucBuf[ 2], (unsigned)ucBuf[ 3], (unsigned)ucBuf[ 4], (unsigned)ucBuf[ 5], (unsigned)ucBuf[ 6], (unsigned)ucBuf[ 7], (unsigned)ucBuf[ 8], (unsigned)ucBuf[ 9], (unsigned)ucBuf[ 10], (unsigned)ucBuf[ 11], (unsigned)ucBuf[ 12], (unsigned)ucBuf[ 13], (unsigned)ucBuf[ 14], (unsigned)ucBuf[ 15]); bValidOption = TRUE; } if (!bValidOption) { pShell->con_printf( "Invalid option.\n"); iExitCode = -1; goto Exit; } Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } return( iExitCode); } /**************************************************************************** Desc: *****************************************************************************/ void FlmDbGetConfigCommand::displayHelp( FlmShell * pShell, char * pszCommand) { if (!pszCommand) { pShell->displayCommand( "dbgetconfig", "Display DB configuration"); } else { pShell->con_printf("Usage:\n"); pShell->con_printf( " %s