//------------------------------------------------------------------------------ // Desc: Command-line environment for FLAIM utilities // // Tabs: 3 // // Copyright (c) 1999-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 "dbshell.h" #include "flm_edit.h" // Imported global variables. FLMBOOL gv_bShutdown = FALSE; FSTATIC RCODE copyStatusFunc( eStatusType eStatus, void * pvParm1, void * pvParm2, void * pvAppData); FSTATIC RCODE renameStatusFunc( eStatusType eStatus, void * pvParm1, void * pvParm2, void * pvAppData); FSTATIC RCODE backupStatusFunc( eStatusType eStatus, void * pvParm1, void * pvParm2, void * pvAppData); FSTATIC void format64BitNum( FLMUINT64 ui64Num, char * pszBuf, FLMBOOL bOutputHex, FLMBOOL bAddCommas = FALSE); FSTATIC void removeChars( char * pszString, char cChar); FSTATIC char * positionToPath( char * pszCommandLine); FSTATIC void extractBaseDirAndWildcard( IF_FileSystem * pFileSystem, char * pszPath, char * pszBase, char * pszWildcard); // Methods /**************************************************************************** Desc: *****************************************************************************/ FlmShell::FlmShell() { m_pScreen = NULL; m_pWindow = NULL; m_ArgPool.poolInit( 512); f_memset( &m_DbList [0], 0, sizeof( m_DbList)); m_pTitleWin = NULL; m_iCurrArgC = 0; m_ppCurrArgV = NULL; m_iLastCmdExitCode = 0; m_bPagingEnabled = FALSE; f_memset( &m_ppCmdList [0], 0, sizeof( m_ppCmdList)); f_memset( &m_ppHistory [0], 0, sizeof( m_ppHistory)); } /**************************************************************************** Desc: *****************************************************************************/ FlmShell::~FlmShell() { FLMUINT uiLoop; 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] != HFDB_NULL) { (void)FlmDbClose( &m_DbList[ uiLoop]); } } } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::setup( void) { FlmCommand * pCommand = NULL; RCODE rc = FERR_OK; // Register dbopen command if( (pCommand = f_new FlmDbOpenCommand) == NULL) { rc = RC_SET( FERR_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( FERR_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( FERR_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( FERR_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( FERR_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( FERR_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( FERR_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( FERR_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( FERR_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; // Register the edit command if( (pCommand = f_new FlmEditCommand) == NULL) { rc = RC_SET( FERR_MEM); goto Exit; } if( RC_BAD( rc = registerCmd( pCommand))) { goto Exit; } pCommand = NULL; Exit: if( pCommand) { pCommand->Release(); } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::registerDatabase( HFDB hDb, FLMUINT * puiDbId) { FLMUINT uiLoop; RCODE rc = FERR_OK; for( uiLoop = 0; uiLoop < MAX_SHELL_OPEN_DB; uiLoop++) { if( m_DbList[ uiLoop] == HFDB_NULL) { m_DbList[ uiLoop] = hDb; *puiDbId = uiLoop; goto Exit; } } rc = RC_SET( FERR_TOO_MANY_OPEN_DBS); Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::getDatabase( FLMUINT uiDbId, HFDB * phDb) { RCODE rc = FERR_OK; if( uiDbId >= MAX_SHELL_OPEN_DB) { rc = RC_SET( FERR_FAILURE); goto Exit; } *phDb = m_DbList[ uiDbId]; Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::deregisterDatabase( FLMUINT uiDbId) { RCODE rc = FERR_OK; if( uiDbId >= MAX_SHELL_OPEN_DB) { rc = RC_SET( FERR_FAILURE); goto Exit; } m_DbList[ uiDbId] = HFDB_NULL; Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ void 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); } } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::parseCmdLine( char * pszString) { FLMUINT uiArgCount = 0; FLMUINT uiCurrToken = 0; FLMUINT uiTokenLen; char * pszCurrToken; FLMBOOL bQuoted; FlmParse Parser; RCODE rc = FERR_OK; m_ArgPool.poolReset(); 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 = FERR_OK; FLMBOOL bValidCommand = FALSE; FLMUINT uiLoop; 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) { gv_bShutdown = TRUE; bValidCommand = TRUE; } 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], "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( "echo", "Echo typed in command"); displayCommand( "cls", "Clear screen"); displayCommand( "exit", "Exit shell"); 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( FERR_NOT_IMPLEMENTED); goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::registerCmd( FlmCommand * pCmd) { RCODE rc = FERR_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( FERR_FAILURE); goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE FlmShell::addCmdHistory( char * pszCmd) { FLMUINT uiLoop; FLMUINT uiSlot; FLMUINT uiCmdLen; RCODE rc = FERR_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 = FERR_OK; char szDir [F_PATH_MAX_SIZE]; DirectoryIterator directoryIterator; char * pszTabCompleteBegin = NULL; IF_FileSystem * pFileSystem = NULL; if( RC_BAD( rc = FTXScreenInit( "dbshell 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; } if( RC_BAD( rc = FTXScreenDisplay( m_pScreen))) { goto Exit; } FTXScreenSetShutdownFlag( m_pScreen, &gv_bShutdown); szBuffer[ 0] = '\0'; for( ;;) { // Refresh the title bar f_strcpy( szThreadName, "Flaim Database Shell"); FTXWinSetCursorPos( m_pTitleWin, 0, 0); FTXWinPrintf( m_pTitleWin, "%s", szThreadName); FTXWinClearToEOL( m_pTitleWin); // Check for shutdown if( gv_bShutdown) { break; } FTXWinGetCursorPos( m_pWindow, NULL, &uiRow); FTXWinSetCursorPos( m_pWindow, 0, uiRow); FTXWinClearToEOL( m_pWindow); if( RC_BAD( f_getcwd( szDir))) { szDir [0] = '\0'; } 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( pFileSystem, pszTabCompleteBegin, szBase, szWildcard); directoryIterator.reset(); directoryIterator.setupForSearch( pFileSystem, 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; } 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( m_pWindow) { FTXWinFree( &m_pWindow); } if( m_pScreen) { FTXScreenFree( &m_pScreen); } if( pFileSystem) { pFileSystem->Release(); } 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; HFDB hDb = HFDB_NULL; FLMUINT uiDbId; RCODE rc = FERR_OK; char * pszRflDir = NULL; char * pszPassword = NULL; char * pszAllowLimited; FLMUINT uiOpenFlags = 0; 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) { uiOpenFlags |= FO_ALLOW_LIMITED; } } if( RC_BAD( rc = FlmDbOpen( ppszArgV[ 1], NULL, pszRflDir, uiOpenFlags, pszPassword, &hDb))) { if( rc != FERR_IO_PATH_NOT_FOUND) { goto Exit; } if( RC_BAD( rc = FlmDbCreate( ppszArgV[ 1], NULL, pszRflDir, NULL, NULL, NULL, &hDb))) { goto Exit; } } if( RC_BAD( rc = pShell->registerDatabase( hDb, &uiDbId))) { goto Exit; } hDb = HFDB_NULL; pShell->con_printf( "Database #%u opened.\n", (unsigned)uiDbId); Exit: if( hDb != HFDB_NULL) { (void)FlmDbClose( &hDb); } 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; HFDB hDb; RCODE rc = FERR_OK; if( iArgC != 2) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( f_stricmp( ppszArgV[ 1], "kill") == 0) { (void)FlmConfig( FLM_KILL_DB_HANDLES, NULL, NULL); pShell->con_printf( "All handles killed, but not necessarily closed.\n"); } else if( f_stricmp( ppszArgV[ 1], "all") == 0) { for( uiDbId = 0; uiDbId < MAX_SHELL_OPEN_DB; uiDbId++) { if( RC_BAD( rc = pShell->getDatabase( uiDbId, &hDb))) { goto Exit; } if( hDb != HFDB_NULL) { if( RC_BAD( rc = pShell->deregisterDatabase( uiDbId))) { goto Exit; } (void)FlmDbClose( &hDb); pShell->con_printf( "Database #%u closed.\n", (unsigned)uiDbId); } } (void)FlmConfig( FLM_CLOSE_UNUSED_FILES, (void *)0, NULL); } else { uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( rc = pShell->getDatabase( uiDbId, &hDb))) { goto Exit; } if( hDb != HFDB_NULL) { if( RC_BAD( rc = pShell->deregisterDatabase( uiDbId))) { goto Exit; } (void)FlmDbClose( &hDb); 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; #define FLM_NO_TRANS 0 #define FLM_UPDATE_TRANS 1 #define FLM_READ_TRANS 2 FLMUINT uiTransType; HFDB hDb; RCODE rc = FERR_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, &hDb)) || hDb == HFDB_NULL) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } (void)FlmDbGetTransType( hDb, &uiTransType); if( f_stricmp( ppszArgV [0], "trbegin") == 0) { if( iArgC < 3) { pShell->con_printf( "Wrong number of parameters.\n"); iExitCode = -1; goto Exit; } if( uiTransType != FLM_NO_TRANS) { pShell->con_printf( "%s transaction is already active on database %u.\n", (char *)(uiTransType == FLM_READ_TRANS ? "A read" : "An update"), (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( !f_stricmp( ppszArgV[ 2], "read")) { if( RC_BAD( rc = FlmDbTransBegin( hDb, FLM_READ_TRANS, FLM_NO_TIMEOUT, NULL))) { goto Exit; } } else if( !f_stricmp( ppszArgV[ 2], "update")) { if( iArgC > 4) { uiTimeout = f_atol( ppszArgV[ 3]); } else { uiTimeout = FLM_NO_TIMEOUT; } if( RC_BAD( rc = FlmDbTransBegin( hDb, FLM_UPDATE_TRANS, uiTimeout, NULL))) { 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( uiTransType == FLM_NO_TRANS) { pShell->con_printf( "There is no active transaction on database %u.\n", (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( RC_BAD( rc = FlmDbTransCommit( hDb))) { goto Exit; } pShell->con_printf( "Transaction committed on database %u.\n", (unsigned)uiDbId); } else if( f_stricmp( ppszArgV[ 0], "trabort") == 0) { if( uiTransType == FLM_NO_TRANS) { pShell->con_printf( "There is no active transaction on database %u.\n", (unsigned)uiDbId); iExitCode = -1; goto Exit; } if( RC_BAD( rc = FlmDbTransAbort( hDb))) { 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 function for reporting progress of database copy *****************************************************************************/ FSTATIC RCODE copyStatusFunc( eStatusType eStatus, void * pvParm1, void *, // pvParm2, void * pvAppData) { RCODE rc = FERR_OK; if (eStatus == FLM_DB_COPY_STATUS) { DB_COPY_INFO * pCopyInfo = (DB_COPY_INFO *)pvParm1; FlmShell * pShell = (FlmShell *)pvAppData; FTX_WINDOW * pWin = pShell->getWindow(); if (pCopyInfo->bNewSrcFile) { FTXWinPrintf( pWin, "\nCopying %s to %s ...\n", pCopyInfo->szSrcFileName, pCopyInfo->szDestFileName); } if( gv_bShutdown) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } FTXWinPrintf( pWin, " %,I64u of %,I64u bytes copied\r", pCopyInfo->ui64BytesCopied, pCopyInfo->ui64BytesToCopy); if( RC_OK( FTXWinTestKB( pWin))) { FLMUINT uiChar; FTXWinInputChar( pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } } } Exit: return( rc); } /**************************************************************************** Desc: Status function for reporting progress of database rename *****************************************************************************/ FSTATIC RCODE renameStatusFunc( eStatusType eStatus, void * pvParm1, void *, // pvParm2, void * pvAppData) { RCODE rc = FERR_OK; if (eStatus == FLM_DB_RENAME_STATUS) { DB_RENAME_INFO * pRenameInfo = (DB_RENAME_INFO *)pvParm1; FlmShell * pShell = (FlmShell *)pvAppData; pShell->con_printf( "Renaming %s to %s ...\n", pRenameInfo->szSrcFileName, pRenameInfo->szDstFileName); } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmDbManageCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMINT iExitCode = 0; RCODE rc = FERR_OK; 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 = FlmDbRemove( 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) { if (RC_BAD( rc = FlmDbCopy( ppszArgV [1], NULL, NULL, ppszArgV [2], NULL, NULL, copyStatusFunc, pShell))) { goto Exit; } pShell->con_printf( "\n\n"); } else { if (RC_BAD( rc = FlmDbRename( ppszArgV [1], NULL, NULL, ppszArgV [2], TRUE, renameStatusFunc, pShell))) { 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: *****************************************************************************/ FSTATIC RCODE backupStatusFunc( eStatusType eStatus, void * pvParm1, void *, // pvParm2, void * pvAppData) { RCODE rc = FERR_OK; if (eStatus == FLM_DB_BACKUP_STATUS) { DB_BACKUP_INFO * pBackupInfo = (DB_BACKUP_INFO *)pvParm1; FlmShell * pShell = (FlmShell *)pvAppData; FTX_WINDOW * pWin = pShell->getWindow(); if (gv_bShutdown) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } FTXWinPrintf( pWin, "%,I64u / %,I64u bytes backed up\r", pBackupInfo->ui64BytesDone, pBackupInfo->ui64BytesToDo); if( RC_OK( FTXWinTestKB( pWin))) { FLMUINT uiChar; FTXWinInputChar( pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } } } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmBackupCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMUINT uiDbId; FLMUINT uiIncSeqNum; HFDB hDb; HFBACKUP hBackup = HFBACKUP_NULL; FLMINT iExitCode = 0; FBackupType eBackupType = FLM_FULL_BACKUP; RCODE rc = FERR_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 = FLM_INCREMENTAL_BACKUP; } } // Get the database ID and handle uiDbId = f_atol( ppszArgV[ 1]); if( RC_BAD( pShell->getDatabase( uiDbId, &hDb)) || hDb == HFDB_NULL) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } if( RC_BAD( rc = FlmDbBackupBegin( hDb, eBackupType, TRUE, &hBackup))) { goto Exit; } if( RC_BAD( rc = FlmDbBackup( hBackup, ppszArgV [2], (const char *)(bUsePasswd ? ppszArgV[3] : NULL), NULL, backupStatusFunc, pShell, &uiIncSeqNum))) { goto Exit; } if( RC_BAD( rc = FlmDbBackupEnd( &hBackup))) { 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( hBackup != HFBACKUP_NULL) { (void)FlmDbBackupEnd( &hBackup); } 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: *****************************************************************************/ class F_LocalRestore : public F_FSRestore { public: F_LocalRestore( FlmShell * pShell) { m_pShell = pShell; m_pWin = pShell->getWindow(); 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; } virtual ~F_LocalRestore() { } FINLINE RCODE setup( char * pszDbPath, char * pszBackupSetPath, char * pszRflDir) { return( F_FSRestore::setup( pszDbPath, pszBackupSetPath, pszRflDir)); } FINLINE RCODE openBackupSet( void) { return( F_FSRestore::openBackupSet()); } FINLINE RCODE openIncFile( FLMUINT uiFileNum) { return( F_FSRestore::openIncFile( uiFileNum)); } FINLINE RCODE openRflFile( FLMUINT uiFileNum) { RCODE rc; m_uiRflFileNum = uiFileNum; if (RC_OK( rc = updateCountDisplay())) { rc = F_FSRestore::openRflFile( uiFileNum); } return( rc); } FINLINE RCODE read( FLMUINT uiLength, void * pvBuffer, FLMUINT * puiBytesRead) { RCODE rc; if (RC_OK( rc =F_FSRestore::read( uiLength, pvBuffer, puiBytesRead))) { if (m_uiRflFileNum) { m_ui64RflBytesRead += (*puiBytesRead); } } return( rc); } FINLINE RCODE close( void) { return( F_FSRestore::close()); } FINLINE RCODE abortFile( void) { return( F_FSRestore::abortFile()); } FINLINE RCODE processUnknown( F_UnknownStream * pUnkStrm) { return( F_FSRestore::processUnknown( pUnkStrm)); } RCODE status( eRestoreStatusType eStatusType, FLMUINT uiTransId, void * pvValue1, void * pvValue2, void * pvValue3, eRestoreActionType * peRestoreAction); private: RCODE report_preamble( void); RCODE report_postamble( void); RCODE updateCountDisplay( void); RCODE reportProgress( BYTE_PROGRESS * pProgress); RCODE reportError( eRestoreActionType * peRestoreAction, RCODE rcErr); RCODE reportBeginTrans( FLMUINT uiTransId); RCODE reportEndTrans( const char * pszAction, FLMUINT uiTransId); FlmShell * m_pShell; FTX_WINDOW * m_pWin; 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: *****************************************************************************/ RCODE F_LocalRestore::report_preamble( void) { RCODE rc = FERR_OK; if( gv_bShutdown) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } if( m_bFirstStatus) { FTXWinClear( m_pWin); m_bFirstStatus = FALSE; } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::report_postamble( void) { RCODE rc = FERR_OK; FTXWinSetCursorPos( m_pWin, 0, 5); f_yieldCPU(); if( RC_OK( FTXWinTestKB( m_pWin))) { FLMUINT uiChar; FTXWinInputChar( m_pWin, &uiChar); if (uiChar == FKB_ESC) { rc = RC_SET( FERR_USER_ABORT); goto Exit; } } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::updateCountDisplay( void) { RCODE rc = FERR_OK; if (m_pWin) { if (RC_BAD(rc = report_preamble())) { goto Exit; } FTXWinSetCursorPos( m_pWin, 0, 2); FTXWinPrintf( m_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); if (RC_BAD(rc = report_postamble())) { goto Exit; } } Exit: return( rc); } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::reportProgress( BYTE_PROGRESS * pProgress) { RCODE rc = FERR_OK; if (RC_BAD(rc = report_preamble())) { goto Exit; } FTXWinSetCursorPos( m_pWin, 0, 1); FTXWinPrintf( m_pWin, "%,I64u / %,I64u bytes restored", pProgress->ui64BytesDone, pProgress->ui64BytesToDo); FTXWinClearToEOL( m_pWin); if (RC_BAD(rc = report_postamble())) { goto Exit; } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::reportError( eRestoreActionType * peAction, RCODE rcErr) { RCODE rc = FERR_OK; FLMUINT uiChar; *peAction = RESTORE_ACTION_CONTINUE; if (RC_BAD(rc = report_preamble())) { goto Exit; } FTXWinSetCursorPos( m_pWin, 0, 6); FTXWinClearToEOL( m_pWin); FTXWinPrintf( m_pWin, "Error: %s. Retry (Y/N): ", FlmErrorString( rcErr)); if( RC_BAD( FTXWinInputChar( m_pWin, &uiChar))) { uiChar = 0; goto Exit; } if( uiChar == 'Y' || uiChar == 'y') { *peAction = RESTORE_ACTION_RETRY; } FTXWinClearToEOL( m_pWin); if (RC_BAD(rc = report_postamble())) { goto Exit; } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::reportBeginTrans( FLMUINT uiTransId) { RCODE rc = FERR_OK; if (RC_BAD(rc = report_preamble())) { goto Exit; } FTXWinSetCursorPos( m_pWin, 0, 5); FTXWinPrintf( m_pWin, "BEGIN_TRANS: ID = 0x%X", uiTransId); FTXWinClearToEOL( m_pWin); if (RC_BAD(rc = report_postamble())) { goto Exit; } Exit: return rc; } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::reportEndTrans( const char * pszAction, FLMUINT uiTransId) { if( m_bFirstStatus) { FTXWinClear( m_pWin); m_bFirstStatus = FALSE; } FTXWinSetCursorPos( m_pWin, 0, 5); FTXWinPrintf( m_pWin, "%s: ID = 0x%X", pszAction, uiTransId); FTXWinClearToEOL( m_pWin); m_uiTransCount++; return( updateCountDisplay()); } /**************************************************************************** Desc: *****************************************************************************/ RCODE F_LocalRestore::status( eRestoreStatusType eStatusType, FLMUINT uiTransId, void * pvValue1, void *, // pvValue2, void *, // pvValue3, eRestoreActionType * peRestoreAction) { RCODE rc = FERR_OK; *peRestoreAction = RESTORE_ACTION_CONTINUE; switch (eStatusType) { case RESTORE_BEGIN_TRANS: rc = reportBeginTrans( uiTransId); break; case RESTORE_COMMIT_TRANS: rc = reportEndTrans( "COMMIT_TRANS", uiTransId); break; case RESTORE_ABORT_TRANS: rc = reportEndTrans( "ABORT_TRANS", uiTransId); break; case RESTORE_PROGRESS: rc = reportProgress( (BYTE_PROGRESS *)pvValue1); break; case RESTORE_WRAP_KEY: rc = reportEndTrans( "WRAP_KEY", uiTransId); break; case RESTORE_ENABLE_ENCRYPTION: rc = reportEndTrans( "ENABLE_ENCRYPTION", uiTransId); break; case RESTORE_ADD_REC: m_uiAddCount++; rc = updateCountDisplay(); break; case RESTORE_DEL_REC: m_uiDeleteCount++; rc = updateCountDisplay(); break; case RESTORE_MOD_REC: m_uiModifyCount++; rc = updateCountDisplay(); break; case RESTORE_RESERVE_DRN: m_uiReserveCount++; rc = updateCountDisplay(); break; case RESTORE_INDEX_SET: m_uiIndexCount++; rc = updateCountDisplay(); break; case RESTORE_ERROR: rc = reportError( peRestoreAction, (RCODE)((FLMUINT)pvValue1)); break; case RESTORE_REDUCE: rc = reportEndTrans( "REDUCE", uiTransId); break; case RESTORE_UPGRADE: rc = reportEndTrans( "UPGRADE_DB", uiTransId); break; case RESTORE_INDEX_SUSPEND: case RESTORE_INDEX_RESUME: case RESTORE_BLK_CHAIN_DELETE: default: break; } return( rc); } /**************************************************************************** Desc: *****************************************************************************/ FLMINT FlmRestoreCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { char * pszRflDir = NULL; FLMINT iExitCode = 0; F_LocalRestore restoreObj( pShell); RCODE rc = FERR_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) { pszRflDir = ppszArgV[ 4]; } if( RC_BAD( rc = FlmDbRestore( ppszArgV [1], NULL, ppszArgV [2], pszRflDir, (const char *)(bUsePasswd ? ppszArgV [3] : NULL), &restoreObj))) { goto Exit; } pShell->con_printf( "\nRestore complete.\n"); Exit: if( RC_BAD( rc)) { pShell->con_printf( "\nError: %e\n", rc); if( !iExitCode) { iExitCode = rc; } } 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: *****************************************************************************/ FLMINT FlmDbConfigCommand::execute( FLMINT iArgC, char ** ppszArgV, FlmShell * pShell) { FLMUINT uiDbId; HFDB hDb; FLMINT iExitCode = 0; RCODE rc = FERR_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, &hDb)) || hDb == HFDB_NULL) { 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 = FlmDbConfig( hDb, FDB_RFL_KEEP_FILES, (void *)((FLMUINT)bEnable), NULL))) { 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 = FlmDbConfig( hDb, FDB_RFL_DIR, ppszArgV[ 3], NULL))) { 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 = FlmDbConfig( hDb, FDB_RFL_FILE_LIMITS, (void *)uiRflMinSize, (void *)uiRflMaxSize))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "rflrolltonextfile") == 0) { if( RC_BAD( rc = FlmDbConfig( hDb, FDB_RFL_ROLL_TO_NEXT_FILE, NULL, NULL))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "rflkeepabortedtrans") == 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 = FlmDbConfig( hDb, FDB_KEEP_ABORTED_TRANS_IN_RFL, (void *)((FLMUINT)bEnable), NULL))) { goto Exit; } } else if( f_stricmp( ppszArgV[ 2], "fileextendsize") == 0) { FLMUINT uiFileExtendSize; if( iArgC < 4) { pShell->con_printf( "Too few parameters.\n"); iExitCode = -1; goto Exit; } uiFileExtendSize = f_atol( ppszArgV[ 3]); if( RC_BAD( rc = FlmDbConfig( hDb, FDB_FILE_EXTEND_SIZE, (void *)uiFileExtendSize, NULL))) { 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); pShell->con_printf( " %s rflkeepabortedtrans \n", pszCommand); pShell->con_printf( " %s fileextendsize \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; HFDB hDb; FLMINT iExitCode = 0; FLMUINT uiArg; FLMUINT uiArg2; FLMBOOL bArg; char szTmpPath[ F_PATH_MAX_SIZE]; char ucBuf[ 256]; RCODE rc = FERR_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, &hDb)) || hDb == HFDB_NULL) { pShell->con_printf( "Invalid database.\n"); iExitCode = -1; goto Exit; } if (f_stricmp( ppszArgV [2], "all") == 0) { bDoAll = TRUE; bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "transid") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_TRANS_ID, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Current Transaction ID = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "dbversion") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_VERSION, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Database Version = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "blocksize") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_BLKSIZ, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Database Block Size = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "language") == 0) { char szLang [20]; if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_DEFAULT_LANG, &uiArg, NULL, NULL))) { goto Exit; } f_languageToStr( uiArg, szLang); pShell->con_printf( "Database Language = %s\n", szLang); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rfldir") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_RFL_DIR, szTmpPath, NULL, NULL))) { goto Exit; } pShell->con_printf( "RFL directory = %s\n", szTmpPath); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rflfilenum") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_RFL_FILE_NUM, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Current RFL file # = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "rflsizelimits") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_RFL_FILE_SIZE_LIMITS, &uiArg, &uiArg2, NULL))) { goto Exit; } 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 = FlmDbGetConfig( hDb, FDB_GET_SIZES, &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 = FlmDbGetConfig( hDb, FDB_GET_RFL_KEEP_FLAG, &bArg, NULL, NULL))) { 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 = FlmDbGetConfig( hDb, FDB_GET_LAST_BACKUP_TRANS_ID, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Last backup transaction ID = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "blockschangedsincebackup") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_BLOCKS_CHANGED_SINCE_BACKUP, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Blocks changed since last backup = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "highestnotusedrflnum") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_RFL_HIGHEST_NU, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Highest Non-Used RFL Number = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "nextincbackupseqnum") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_NEXT_INC_BACKUP_SEQ_NUM, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Next Incremental Backup Sequence # = %u\n", (unsigned)uiArg); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "serialnumber") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_SERIAL_NUMBER, &ucBuf [0], NULL, NULL))) { goto Exit; } 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( bDoAll || f_stricmp( ppszArgV[ 2], "rflkeepabortedtrans") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_KEEP_ABORTED_TRANS_IN_RFL_FLAG, &bArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "Keep Aborted Trans in RFL = %s\n", bArg ? "Yes" : "No"); bValidOption = TRUE; } if( bDoAll || f_stricmp( ppszArgV[ 2], "fileextendsize") == 0) { if (RC_BAD( rc = FlmDbGetConfig( hDb, FDB_GET_FILE_EXTEND_SIZE, &uiArg, NULL, NULL))) { goto Exit; } pShell->con_printf( "File Extend Size = %u\n", (unsigned)uiArg); 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