Files
mars-flaim/flaim/util/dbshell.cpp
ahodgkinson f54e6ce080 Changed license to LGPL.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1009 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2007-01-23 09:38:48 +00:00

4306 lines
90 KiB
C++

//------------------------------------------------------------------------------
// 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 <DbFileName> [<RflPath> [<Password> [<AllowLimited>]]]\n");
pShell->con_printf(" <AllowLimited> : 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 <db# | ALL>\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 <timeout>]\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 <DbFileName>\n");
}
else
{
pShell->con_printf( " %s <SrcDbFileName> <DestDbFileName>\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 <database_path> <backup_name> [<password> [\"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 <RestoreToDbName> <BackupPath> [<password> [<RFL Dir>]]\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 <db#> rflkeepfiles <on|off>\n", pszCommand);
pShell->con_printf( " %s <db#> rfldir <DirectoryName>\n", pszCommand);
pShell->con_printf( " %s <db#> rflfilelimits <MinRflSize> <MaxRflSize>\n",
pszCommand);
pShell->con_printf( " %s <db#> rolltonextfile\n", pszCommand);
pShell->con_printf( " %s <db#> rflkeepabortedtrans <on|off>\n", pszCommand);
pShell->con_printf( " %s <db#> fileextendsize <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 <db#> <option>\n", pszCommand);
pShell->con_printf( " <option> may be one of the following:\n");
pShell->con_printf( " transid\n");
pShell->con_printf( " dbversion\n");
pShell->con_printf( " language\n");
pShell->con_printf( " blocksize\n");
pShell->con_printf( " rflfilenum\n");
pShell->con_printf( " diskusage\n");
pShell->con_printf( " rflkeepfiles\n");
pShell->con_printf( " lastbackuptransid\n");
pShell->con_printf( " blockschangedsincebackup\n");
pShell->con_printf( " highestnotusedrflnum\n");
pShell->con_printf( " nextincbackupseqnum\n");
pShell->con_printf( " serialnumber\n");
pShell->con_printf( " rflkeepabortedtrans\n");
pShell->con_printf( " fileextendsize\n");
pShell->con_printf( " all (will print all of the above)\n");
}
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL FlmDbGetConfigCommand::canPerformCommand(
char * pszCommand)
{
return( (f_stricmp( "dbgetconfig", pszCommand) == 0)
? TRUE
: FALSE);
}
/****************************************************************************
Desc: Constructor
*****************************************************************************/
FlmDbContext::FlmDbContext()
{
f_memset( m_DbContexts, 0, sizeof( m_DbContexts));
m_uiCurrDbId = 0;
}
/****************************************************************************
Desc: Destructor
*****************************************************************************/
FlmDbContext::~FlmDbContext( void)
{
FLMUINT uiDbId;
for( uiDbId = 0; uiDbId < MAX_DBCONTEXT_OPEN_DB; uiDbId++)
{
if (m_DbContexts [uiDbId].hDb != HFDB_NULL)
{
(void)FlmDbClose( &m_DbContexts[ uiDbId].hDb);
}
}
}
/****************************************************************************
Desc: Get an available database ID.
*****************************************************************************/
FLMBOOL FlmDbContext::getAvailDbId(
FLMUINT * puiDbId
)
{
FLMUINT uiDbId = 0;
while (uiDbId < MAX_DBCONTEXT_OPEN_DB &&
m_DbContexts [uiDbId].hDb != HFDB_NULL)
{
uiDbId++;
}
*puiDbId = uiDbId;
return( (FLMBOOL)((uiDbId < MAX_DBCONTEXT_OPEN_DB) ? TRUE : FALSE));
}
/****************************************************************************
Desc: Set the database handle for a database ID
*****************************************************************************/
FLMBOOL FlmDbContext::setDb(
FLMUINT uiDbId,
HFDB hDb)
{
if (uiDbId < MAX_DBCONTEXT_OPEN_DB)
{
m_DbContexts [uiDbId].hDb = hDb;
return( TRUE);
}
else
{
return( FALSE);
}
}
/****************************************************************************
Desc: Get the database handle for a database ID
*****************************************************************************/
HFDB FlmDbContext::getDb(
FLMUINT uiDbId)
{
return( (uiDbId < MAX_DBCONTEXT_OPEN_DB)
? m_DbContexts [uiDbId].hDb
: HFDB_NULL);
}
/****************************************************************************
Desc: Set the current container for a database ID
*****************************************************************************/
FLMBOOL FlmDbContext::setCurrContainer(
FLMUINT uiDbId,
FLMUINT uiContainer)
{
if (uiDbId < MAX_DBCONTEXT_OPEN_DB)
{
m_DbContexts [uiDbId].uiCurrContainer = uiContainer;
return( TRUE);
}
else
{
return( FALSE);
}
}
/****************************************************************************
Desc: Get the current container for a database ID
*****************************************************************************/
FLMUINT FlmDbContext::getCurrContainer(
FLMUINT uiDbId)
{
return( (FLMUINT)((uiDbId < MAX_DBCONTEXT_OPEN_DB)
? m_DbContexts [uiDbId].uiCurrContainer
: (FLMUINT)0));
}
/****************************************************************************
Desc: Set the current index for a database ID
*****************************************************************************/
FLMBOOL FlmDbContext::setCurrIndex(
FLMUINT uiDbId,
FLMUINT uiIndex)
{
if (uiDbId < MAX_DBCONTEXT_OPEN_DB)
{
m_DbContexts [uiDbId].uiCurrIndex = uiIndex;
return( TRUE);
}
else
{
return( FALSE);
}
}
/****************************************************************************
Desc: Get the current index for a database ID
*****************************************************************************/
FLMUINT FlmDbContext::getCurrIndex(
FLMUINT uiDbId)
{
return( (FLMUINT)((uiDbId < MAX_DBCONTEXT_OPEN_DB)
? m_DbContexts [uiDbId].uiCurrIndex
: (FLMUINT)0));
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL FlmDbContext::setCurrId(
FLMUINT uiDbId,
FLMUINT uiId)
{
if (uiDbId < MAX_DBCONTEXT_OPEN_DB)
{
m_DbContexts [uiDbId].uiCurrId = uiId;
return( TRUE);
}
else
{
return( FALSE);
}
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMUINT FlmDbContext::getCurrId(
FLMUINT uiDbId)
{
return( (FLMUINT)((uiDbId < MAX_DBCONTEXT_OPEN_DB)
? m_DbContexts [uiDbId].uiCurrId
: (FLMUINT)0));
}
/****************************************************************************
Desc: Set the current search flagsfor a database ID
*****************************************************************************/
FLMBOOL FlmDbContext::setCurrSearchFlags(
FLMUINT uiDbId,
FLMUINT uiSearchFlags)
{
if (uiDbId < MAX_DBCONTEXT_OPEN_DB)
{
m_DbContexts [uiDbId].uiCurrSearchFlags = uiSearchFlags;
return( TRUE);
}
else
{
return( FALSE);
}
}
/****************************************************************************
Desc: Get the current search flags for a database ID
*****************************************************************************/
FLMUINT FlmDbContext::getCurrSearchFlags(
FLMUINT uiDbId)
{
return( (FLMUINT)((uiDbId < MAX_DBCONTEXT_OPEN_DB)
? m_DbContexts [uiDbId].uiCurrSearchFlags
: (FLMUINT)FO_INCL));
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMINT FlmFileSysCommand::execute(
FLMINT iArgC,
char ** ppszArgV,
FlmShell * pShell)
{
FLMINT iExitCode = 0;
RCODE rc = FERR_OK;
FLMUINT uiLoop = 0;
FLMBOOL bForce = FALSE;
IF_FileSystem * pFileSystem = NULL;
IF_DirHdl * pDir = NULL;
if (RC_BAD( rc = FlmGetFileSystem( &pFileSystem)))
{
goto Exit;
}
// Delete the file
if (f_stricmp( ppszArgV [0], "delete") == 0 ||
f_stricmp( ppszArgV [0], "del") == 0 ||
f_stricmp( ppszArgV [0], "rm") == 0)
{
for ( uiLoop = 1; uiLoop < (FLMUINT)iArgC; uiLoop++)
{
if( ppszArgV[uiLoop][0] == '/')
{
switch( ppszArgV[uiLoop][1])
{
case 'f':
case 'F':
bForce = TRUE;
break;
default:
pShell->con_printf( "Unknown option: %s.\n", ppszArgV[uiLoop]);
iExitCode = -1;
goto Exit;
}
}
else
{
break;
}
}
if( ( iArgC - uiLoop) < 1)
{
pShell->con_printf( "Wrong number of parameters.\n");
iExitCode = -1;
goto Exit;
}
if( bForce)
{
pFileSystem->setReadOnly( ppszArgV[uiLoop], FALSE);
}
if( RC_BAD( rc = pFileSystem->deleteFile( ppszArgV[ uiLoop])))
{
goto Exit;
}
pShell->con_printf( "\nFile deleted.\n");
}
else if (f_stricmp( ppszArgV [0], "cd") == 0 ||
f_stricmp( ppszArgV [0], "chdir") == 0)
{
if (iArgC > 1)
{
if( RC_BAD( f_chdir( (const char *)ppszArgV [1])))
{
pShell->con_printf( "Error changing directory\n");
}
}
}
else if(f_stricmp( "rename", ppszArgV[0]) == 0 ||
f_stricmp( "move", ppszArgV[0]) == 0 ||
f_stricmp( "mv", ppszArgV[0]) == 0 )
{
FLMBOOL bOverwrite = FALSE;
for( uiLoop = 1; uiLoop < (FLMUINT)iArgC; uiLoop++)
{
if ( ppszArgV[ uiLoop][0] == '/')
{
switch( ppszArgV[uiLoop][1])
{
case 'f':
case 'F':
bForce = TRUE;
break;
case 'o':
case 'O':
bOverwrite = TRUE;
break;
default:
pShell->con_printf( "Unknown option: %s\n", &ppszArgV[uiLoop]);
iExitCode = -1;
goto Exit;
}
}
else
{
break;
}
}
// The remaining two parameters are the source and destination
if ( ( iArgC - uiLoop) < 2)
{
pShell->con_printf( "You must specify a source and destination.\n");
iExitCode = -1;
goto Exit;
}
if ( RC_BAD( rc = pFileSystem->doesFileExist( ppszArgV[uiLoop])))
{
goto Exit;
}
if ( pFileSystem->isDir( ppszArgV[uiLoop + 1]))
{
char szFilename[ F_FILENAME_SIZE];
// If the second param is a directory we'll assume the user wants to
// move the file into it with the same filename.
pFileSystem->pathReduce( ppszArgV[uiLoop], NULL, szFilename);
pFileSystem->pathAppend( szFilename, ppszArgV[uiLoop + 1]);
}
if( RC_OK( pFileSystem->doesFileExist( ppszArgV[uiLoop + 1])))
{
if ( !bOverwrite)
{
FLMUINT uiChar;
pShell->con_printf( "%s exists. Overwrite? (Y/N)", ppszArgV[ uiLoop + 1]);
for(;;)
{
if( RC_OK( FTXWinTestKB( pShell->getWindow())))
{
FTXWinInputChar( pShell->getWindow(), &uiChar);
// Echo char back to the user
pShell->con_printf( "%c\n", uiChar);
if ( uiChar == 'Y' || uiChar == 'y')
{
bOverwrite = TRUE;
}
else
{
rc = RC_SET( FERR_USER_ABORT);
goto Exit;
}
break;
}
}
}
if ( bOverwrite)
{
if ( bForce)
{
pFileSystem->setReadOnly( ppszArgV[uiLoop + 1], FALSE);
pShell->con_printf( "Error changing file attributes. ");
goto Exit;
}
if ( RC_BAD( rc = pFileSystem->deleteFile( ppszArgV[uiLoop + 1])))
{
pShell->con_printf( "Error removing destination file. ");
goto Exit;
}
}
}
if ( RC_BAD( rc = pFileSystem->renameFile( ppszArgV[uiLoop],
ppszArgV[uiLoop + 1])))
{
goto Exit;
}
pShell->con_printf( "%s -> %s\n",
ppszArgV[uiLoop], ppszArgV[uiLoop + 1]);
}
else if(f_stricmp( "copy", ppszArgV[0]) == 0 ||
f_stricmp( "cp", ppszArgV[0]) == 0)
{
FLMBOOL bOverwrite = FALSE;
FLMUINT64 ui64BytesCopied = 0;
for( uiLoop = 1; uiLoop < (FLMUINT)iArgC; uiLoop++)
{
if ( ppszArgV[ uiLoop][0] == '/')
{
switch( ppszArgV[uiLoop][1])
{
case 'f':
case 'F':
bForce = TRUE;
break;
case 'o':
case 'O':
bOverwrite = TRUE;
break;
default:
pShell->con_printf( "Unknown option: %s\n", &ppszArgV[uiLoop]);
iExitCode = -1;
goto Exit;
}
}
else
{
break;
}
}
// The remaining two parameters are the source and destination
if ( ( iArgC - uiLoop) < 2)
{
pShell->con_printf( "You must specify a source and destination.\n");
iExitCode = -1;
goto Exit;
}
if ( RC_BAD( rc = pFileSystem->doesFileExist( ppszArgV[uiLoop])))
{
goto Exit;
}
if ( pFileSystem->isDir( ppszArgV[uiLoop + 1]))
{
char szFilename[ F_FILENAME_SIZE];
// If the second param is a directory we'll assume the user wants to
// copy the file into it with the same filename.
pFileSystem->pathReduce( ppszArgV[uiLoop], NULL, szFilename);
pFileSystem->pathAppend( szFilename, ppszArgV[uiLoop + 1]);
}
if ( RC_OK( pFileSystem->doesFileExist( ppszArgV[uiLoop + 1])))
{
if ( !bOverwrite)
{
FLMUINT uiChar;
pShell->con_printf( "%s exists. Overwrite? (Y/N)", ppszArgV[ uiLoop + 1]);
for(;;)
{
if( RC_OK( FTXWinTestKB( pShell->getWindow())))
{
FTXWinInputChar( pShell->getWindow(), &uiChar);
// Echo char back to the user
pShell->con_printf( "%c\n", uiChar);
if ( uiChar == 'Y' || uiChar == 'y')
{
bOverwrite = TRUE;
}
else
{
rc = RC_SET( FERR_USER_ABORT);
goto Exit;
}
break;
}
}
}
if ( bOverwrite)
{
// There's no sense in changing a file's attributes if we aren't
// going to overwrite it.
if ( bForce)
{
pFileSystem->setReadOnly( ppszArgV[ uiLoop + 1], FALSE);
}
}
}
if ( RC_BAD( rc = pFileSystem->copyFile(
ppszArgV[uiLoop], ppszArgV[uiLoop +1], bOverwrite, &ui64BytesCopied)))
{
goto Exit;
}
pShell->con_printf( "%s copied to %s (%I64u bytes copied)\n",
ppszArgV[uiLoop], ppszArgV[uiLoop + 1], ui64BytesCopied);
}
else if (f_stricmp( "ls", ppszArgV [0]) == 0 ||
f_stricmp( "dir", ppszArgV [0]) == 0)
{
char szDir [F_PATH_MAX_SIZE];
char szBaseName [F_FILENAME_SIZE];
FLMUINT uiLineCount;
FTX_WINDOW * pWindow = pShell->getWindow();
FLMUINT uiMaxLines;
FLMUINT uiNumCols;
FLMUINT uiChar;
FTXWinGetCanvasSize( pWindow, &uiNumCols, &uiMaxLines);
uiMaxLines--;
if( iArgC > 1)
{
if (RC_BAD( rc = pFileSystem->pathReduce(
ppszArgV [1], szDir, szBaseName)))
{
goto Exit;
}
if (!szDir [0])
{
f_strcpy( szDir, ".");
}
if (RC_BAD( rc = pFileSystem->openDir( szDir,
(char *)szBaseName, &pDir)))
{
goto Exit;
}
}
else
{
if (RC_BAD( rc = pFileSystem->openDir( ".", NULL, &pDir)))
{
goto Exit;
}
}
pShell->con_printf( "%-20s %25s\n", "File Name", "File Size");
uiLineCount = 1;
for (;;)
{
if (RC_BAD( rc = pDir->next()))
{
if (rc == FERR_IO_NO_MORE_FILES)
{
rc = FERR_OK;
break;
}
else
{
goto Exit;
}
}
if (uiLineCount == uiMaxLines)
{
pShell->con_printf(
"...(more, press any character to continue, ESC to quit)");
uiChar = 0;
for (;;)
{
if( RC_OK( FTXWinTestKB( pWindow)))
{
FTXWinInputChar( pWindow, &uiChar);
break;
}
if (gv_bShutdown)
{
uiChar = FKB_ESC;
break;
}
f_yieldCPU();
}
if (uiChar == FKB_ESC)
{
break;
}
pShell->con_printf(
"\r \r");
uiLineCount = 0;
}
if (pDir->currentItemIsDir())
{
pShell->con_printf( "%-20s %25s\n", pDir->currentItemName(),
"<DIR>");
}
else
{
char szTmpBuf [60];
format64BitNum( (FLMUINT64)pDir->currentItemSize(),
szTmpBuf, FALSE, TRUE);
pShell->con_printf( "%-20s %25s\n", pDir->currentItemName(),
szTmpBuf);
}
uiLineCount++;
}
}
else
{
// Should never happen!
flmAssert( 0);
}
Exit:
if( pDir)
{
pDir->Release();
}
if( pFileSystem)
{
pFileSystem->Release();
}
if( RC_BAD( rc))
{
pShell->con_printf( "\nError: %e\n", rc);
if( !iExitCode)
{
iExitCode = rc;
}
}
return( iExitCode);
}
/****************************************************************************
Desc:
*****************************************************************************/
void FlmFileSysCommand::displayHelp(
FlmShell * pShell,
char * pszCommand)
{
if (!pszCommand)
{
pShell->displayCommand( "delete, del, rm", "Delete a file. Options: "
"/O - Overwrite /F - Force");
pShell->displayCommand( "cd (or chdir)", "Change directories");
pShell->displayCommand( "dir, ls", "List files");
pShell->displayCommand( "copy, cp", "Copy files. Options: "
"/O - Overwrite /F - Force");
pShell->displayCommand( "rename, move, mv", "Move a file. Options: "
"/O - Overwrite /F - Force");
}
else
{
pShell->con_printf("Usage:\n");
if (f_stricmp( "cd", pszCommand) == 0)
{
pShell->con_printf( " %s <Directory>\n", pszCommand);
}
else if (f_stricmp( "ls", pszCommand) == 0 ||
f_stricmp( "dir", pszCommand) == 0)
{
pShell->con_printf( " %s [FileMask]\n", pszCommand);
}
else
{
pShell->con_printf( " %s <filename>\n", pszCommand);
}
}
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL FlmFileSysCommand::canPerformCommand(
char * pszCommand)
{
return( (f_stricmp( "delete", pszCommand) == 0 ||
f_stricmp( "del", pszCommand) == 0 ||
f_stricmp( "rm", pszCommand) == 0 ||
f_stricmp( "ls", pszCommand) == 0 ||
f_stricmp( "dir", pszCommand) == 0 ||
f_stricmp( "cd", pszCommand) == 0 ||
f_stricmp( "chdir", pszCommand) == 0 ||
f_stricmp( "del", pszCommand) == 0 ||
f_stricmp( "rm", pszCommand) == 0 ||
f_stricmp( "copy", pszCommand) == 0 ||
f_stricmp( "cp", pszCommand) == 0 ||
f_stricmp( "move", pszCommand) == 0 ||
f_stricmp( "mv", pszCommand) == 0 ||
f_stricmp( "rename", pszCommand) == 0)
? TRUE
: FALSE);
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMINT FlmEditCommand::execute(
FLMINT iArgC,
char ** ppszArgV,
FlmShell * pShell)
{
RCODE rc = FERR_OK;
FLMINT iExitCode = 0;
HFDB hDb = HFDB_NULL;
FLMUINT uiDbId;
F_RecEditor * pRecEditor = NULL;
FTX_SCREEN * pScreen = NULL;
FTX_WINDOW * pTitleWin = NULL;
char szTitle[ 80];
FLMUINT Cols;
FLMUINT Rows;
HFDB hNewDb = HFDB_NULL;
char * pszRflDir = NULL;
char * pszPassword = NULL;
char * pszAllowLimited;
FLMUINT uiOpenFlags = 0;
if( iArgC < 1)
{
pShell->con_printf( "Wrong number of parameters.\n");
iExitCode = -1;
goto Exit;
}
if( iArgC >= 2)
{
char * pszName = ppszArgV [1];
while (*pszName)
{
if (*pszName < '0' || *pszName > '9')
{
break;
}
pszName++;
}
if (*pszName)
{
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, &hNewDb)))
{
pShell->con_printf( "Error opening database: %e.\n", rc);
iExitCode = -1;
goto Exit;
}
if( RC_BAD( rc = pShell->registerDatabase( hNewDb, &uiDbId)))
{
pShell->con_printf( "Error registering database: %e.\n", rc);
iExitCode = -1;
goto Exit;
}
hNewDb = HFDB_NULL;
pShell->con_printf( "Database #%u opened.\n", (unsigned)uiDbId);
}
else
{
uiDbId = f_atoi( ppszArgV[ 1]);
}
}
else
{
uiDbId = 0;
}
if (RC_BAD( rc = pShell->getDatabase( uiDbId, &hDb)))
{
pShell->con_printf( "Error getting database handle: %e.\n", rc);
iExitCode = -1;
goto Exit;
}
if (hDb == HFDB_NULL)
{
pShell->con_printf( "Database %u not open.\n", uiDbId);
iExitCode = -1;
goto Exit;
}
f_sprintf( szTitle,
"Database Edit for FLAIM [DB=%s/BUILD=%s]",
FLM_CUR_FILE_FORMAT_VER_STR, __DATE__);
if( RC_BAD( FTXScreenInit( szTitle, &pScreen)))
{
iExitCode = -1;
goto Exit;
}
if( RC_BAD( FTXWinInit( pScreen, 0, 1, &pTitleWin)))
{
iExitCode = -1;
goto Exit;
}
FTXWinPaintBackground( pTitleWin, FLM_RED);
FTXWinPrintStr( pTitleWin, szTitle);
FTXWinSetCursorType( pTitleWin, FLM_CURSOR_INVISIBLE);
FTXWinOpen( pTitleWin);
if ((pRecEditor = f_new F_RecEditor()) == NULL)
{
rc = RC_SET( FERR_MEM);
pShell->con_printf( "Error allocating editor object: %e.\n", rc);
iExitCode = -1;
goto Exit;
}
if( RC_BAD( rc = pRecEditor->Setup( pScreen)))
{
pShell->con_printf( "Error setting up editor object: %e.\n", rc);
iExitCode = -1;
goto Exit;
}
pRecEditor->setDefaultSource( hDb, FLM_DATA_CONTAINER);
pRecEditor->setShutdown( &gv_bShutdown);
// Start up the editor
FTXScreenGetSize( pScreen, &Cols, &Rows);
FTXScreenDisplay( pScreen);
pRecEditor->interactiveEdit( 0, 1, Cols - 1, Rows - 1);
Exit:
if( hNewDb != HFDB_NULL)
{
(void)FlmDbClose( &hNewDb);
}
if( pRecEditor)
{
pRecEditor->Release();
pRecEditor = NULL;
}
FTXScreenFree( &pScreen);
return( iExitCode);
}
/****************************************************************************
Desc: displayHelp - print a help message.
*****************************************************************************/
void FlmEditCommand::displayHelp(
FlmShell * pShell,
char * pszCommand)
{
if (!pszCommand)
{
pShell->displayCommand( "edit", "Edit a database (DOM Editor)");
}
else
{
pShell->con_printf("Usage:\n");
pShell->con_printf( " %s [db#] (if db# is omitted, 0 is used)\n",
pszCommand);
pShell->con_printf( " OR\n");
pShell->con_printf( " %s <DbFileName> [<RflPath> [<Password> [<AllowLimited>]]]\n", pszCommand);
pShell->con_printf( " <AllowLimited> = TRUE | FALSE\n");
pShell->con_printf( " This form of the command will open the database before editing.\n");
}
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL FlmEditCommand::canPerformCommand(
char * pszCommand)
{
return( (f_stricmp( "edit", pszCommand) == 0)
? TRUE
: FALSE);
}
/****************************************************************************
Desc:
*****************************************************************************/
RCODE DirectoryIterator::setupDirectories(
char * pszBaseDir,
char * pszExtendedDir)
{
RCODE rc = FERR_OK;
flmAssert( !m_pszBaseDir && !m_pszExtendedDir && !m_pszResolvedDir);
if( RC_BAD( rc = f_alloc( MAX_PATH_SIZE, &m_pszBaseDir)))
{
goto Exit;
}
f_strcpy( m_pszBaseDir, pszBaseDir);
if ( m_pszBaseDir[ f_strlen(m_pszBaseDir) - 1] != SLASH)
{
f_strcat( m_pszBaseDir, SSLASH);
}
if( *pszExtendedDir)
{
if( f_strlen( pszExtendedDir) < MAX_PATH_SIZE)
{
if( RC_BAD( f_alloc( MAX_PATH_SIZE, &m_pszExtendedDir)))
{
goto Exit;
}
f_strcpy( m_pszExtendedDir, pszExtendedDir);
}
else
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
}
if ( !m_pszResolvedDir)
{
if( RC_BAD( rc = f_alloc( MAX_PATH_SIZE, &m_pszResolvedDir)))
{
goto Exit;
}
}
if ( RC_BAD( rc = resolveDir()))
{
goto Exit;
}
Exit:
return rc;
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL DirectoryIterator::isInSet(
char * pszFilename)
{
char * pszTemp = NULL;
char * pszSave = NULL;
FLMBOOL bFound = FALSE;
FLMUINT uiLoop = 0;
if( RC_BAD( f_alloc( f_strlen( m_pszResolvedDir) +
f_strlen( pszFilename) + 1, &pszTemp)))
{
goto Exit;
}
// Move past the prefix since that is not stored in the match list.
if( f_strstr( pszFilename, m_pszResolvedDir) == pszFilename)
{
f_strcpy( pszTemp, pszFilename + f_strlen( m_pszResolvedDir));
}
for( uiLoop = 0; uiLoop < m_uiTotalMatches; uiLoop++)
{
if ( f_stricmp( pszTemp, m_ppszMatchList[uiLoop]) == 0)
{
bFound = TRUE;
break;
}
}
if ( pszTemp)
{
f_free( &pszTemp);
}
if ( pszSave)
{
f_strcpy( pszFilename, pszSave);
f_free( &pszSave);
}
Exit:
return bFound;
}
/****************************************************************************
Desc:
*****************************************************************************/
RCODE DirectoryIterator::setupForSearch(
IF_FileSystem * pFileSystem,
char * pszBaseDir,
char * pszExtendedDir,
char * pszPattern)
{
RCODE rc = FERR_OK;
if ( RC_BAD( rc = setupDirectories( pszBaseDir, pszExtendedDir)))
{
goto Exit;
}
flmAssert( !m_pDirHdl && !m_ppszMatchList);
if ( RC_BAD( pFileSystem->openDir( m_pszResolvedDir,
(char *)pszPattern, &m_pDirHdl)))
{
goto Exit;
}
// First pass - determine the number of matches
while( RC_OK( m_pDirHdl->next()))
{
m_uiTotalMatches++;
}
m_pDirHdl->Release();
m_pDirHdl = NULL;
if( RC_BAD( rc = f_alloc(
sizeof( char *) * m_uiTotalMatches, &m_ppszMatchList)))
{
goto Exit;
}
f_memset( m_ppszMatchList, 0, m_uiTotalMatches * sizeof( char *));
// Reopen the directory and copy the matches
if ( RC_BAD( pFileSystem->openDir( m_pszResolvedDir,
(char *)pszPattern, &m_pDirHdl)))
{
goto Exit;
}
m_uiCurrentMatch = 0;
while ( RC_OK( m_pDirHdl->next()))
{
if( RC_BAD( rc = f_alloc(
f_strlen( m_pDirHdl->currentItemName()) + 1,
&m_ppszMatchList[m_uiCurrentMatch])))
{
goto Exit;
}
f_strcpy( m_ppszMatchList[m_uiCurrentMatch],
m_pDirHdl->currentItemName());
m_uiCurrentMatch++;
}
m_uiCurrentMatch = 0;
m_bInitialized = TRUE;
Exit:
return( rc);
}
/****************************************************************************
Desc:
*****************************************************************************/
void DirectoryIterator::next(
char * pszReturn,
FLMBOOL bCompletePath)
{
if ( m_uiCurrentMatch >= m_uiTotalMatches)
{
m_uiCurrentMatch = 0;
}
if ( pszReturn)
{
*pszReturn = '\0';
if ( bCompletePath)
{
f_strcpy( pszReturn, getResolvedPath());
}
f_strcat( pszReturn, m_ppszMatchList[ m_uiCurrentMatch]);
}
m_uiCurrentMatch++;
}
/****************************************************************************
Desc:
*****************************************************************************/
void DirectoryIterator::prev(
char * pszReturn,
FLMBOOL bCompletePath)
{
if( m_uiCurrentMatch == 0)
{
m_uiCurrentMatch = m_uiTotalMatches;
}
m_uiCurrentMatch--;
if ( pszReturn)
{
*pszReturn = '\0';
if ( bCompletePath)
{
f_strcpy( pszReturn, getResolvedPath());
}
f_strcat( pszReturn, m_ppszMatchList[ m_uiCurrentMatch]);
}
}
/****************************************************************************
Desc:
*****************************************************************************/
void DirectoryIterator::first(
char * pszReturn,
FLMBOOL bCompletePath)
{
if ( pszReturn)
{
*pszReturn = '\0';
if ( bCompletePath)
{
f_strcpy( pszReturn, getResolvedPath());
}
f_strcat( pszReturn, m_ppszMatchList[ 0]);
}
}
/****************************************************************************
Desc:
*****************************************************************************/
void DirectoryIterator::last(
char * pszReturn,
FLMBOOL bCompletePath)
{
if ( pszReturn)
{
*pszReturn = '\0';
if ( bCompletePath)
{
f_strcpy( pszReturn, getResolvedPath());
}
f_strcat( pszReturn, m_ppszMatchList[ m_uiTotalMatches - 1]);
}
}
/****************************************************************************
Desc:
*****************************************************************************/
RCODE DirectoryIterator::resolveDir( void)
{
RCODE rc = FERR_OK;
FLMUINT uiIndex = 0;
char szTemp[ MAX_PATH_SIZE];
IF_FileSystem * pFileSystem = NULL;
if( !m_pszExtendedDir)
{
f_strcpy( m_pszResolvedDir, m_pszBaseDir);
goto Exit;
}
if( RC_BAD( rc = FlmGetFileSystem( &pFileSystem)))
{
goto Exit;
}
// If it begins with a SLASH, just go to the root
if ( m_pszExtendedDir[0] == SLASH)
{
if( RC_BAD( rc = extractRoot( m_pszBaseDir, szTemp)))
{
goto Exit;
}
f_strcpy( m_pszResolvedDir, szTemp);
f_strcat( m_pszResolvedDir, &m_pszExtendedDir[1]);
goto Exit;
}
// I think this can only happen on windows and NetWare
else if (isDriveSpec( m_pszExtendedDir))
{
// We have been given a fully-specified drive path
f_strcpy( m_pszResolvedDir, m_pszExtendedDir);
goto Exit;
}
// For each ".." reduce the base path by one
for(;;)
{
if( (f_strlen( &m_pszExtendedDir[uiIndex]) >= f_strlen( PARENT_DIR)) &&
f_memcmp( &m_pszExtendedDir[uiIndex], PARENT_DIR, f_strlen( PARENT_DIR)) == 0)
{
uiIndex += f_strlen( PARENT_DIR);
if ( m_pszExtendedDir[uiIndex] == SLASH)
{
uiIndex++;
}
pFileSystem->pathReduce( m_pszBaseDir, szTemp, NULL);
f_strcpy( m_pszBaseDir, szTemp);
if ( m_pszBaseDir[ f_strlen(m_pszBaseDir) - 1] != SLASH)
{
f_strcat( m_pszBaseDir, SSLASH);
}
}
else
{
break;
}
}
// Tack on whatever's left
f_strcpy( m_pszResolvedDir, m_pszBaseDir);
if( m_pszResolvedDir[f_strlen( m_pszResolvedDir) - 1] != SLASH)
{
// Put the slash back on. pathReduce likes to take it off.
f_strcat( m_pszResolvedDir, SSLASH);
}
f_strcat( m_pszResolvedDir, &m_pszExtendedDir[uiIndex]);
Exit:
if( pFileSystem)
{
pFileSystem->Release();
}
return( rc);
}
/****************************************************************************
Desc:
*****************************************************************************/
void DirectoryIterator::reset( void)
{
if( m_pszBaseDir)
{
f_free( &m_pszBaseDir);
}
if( m_pszExtendedDir)
{
f_free( &m_pszExtendedDir);
}
if( m_pszResolvedDir)
{
f_free( &m_pszResolvedDir);
m_pszResolvedDir = NULL;
}
if( m_pDirHdl)
{
m_pDirHdl->Release();
m_pDirHdl = NULL;
}
if( m_ppszMatchList)
{
for( FLMUINT uiLoop = 0; uiLoop < m_uiTotalMatches; uiLoop++)
{
f_free( &m_ppszMatchList[uiLoop]);
}
f_free( &m_ppszMatchList);
m_ppszMatchList = NULL;
}
m_uiCurrentMatch = 0;
m_uiTotalMatches = 0;
m_bInitialized = FALSE;
}
/****************************************************************************
Desc:
*****************************************************************************/
FLMBOOL DirectoryIterator::isDriveSpec(
char * pszPath)
{
FLMBOOL bIsDriveSpec = FALSE;
char * pszTemp = NULL;
if ((pszTemp = (char *)f_strchr( pszPath, ':')) != NULL)
{
if( *(pszTemp + 1) == SLASH)
{
bIsDriveSpec = TRUE;
}
#ifdef FLM_NLM
// Netware accepts both front and back slashes
else if( *(pszTemp + 1) == FWSLASH)
{
bIsDriveSpec = TRUE;
}
#endif
}
return bIsDriveSpec;
}
/****************************************************************************
Desc:
*****************************************************************************/
RCODE DirectoryIterator::extractRoot(
char * pszPath,
char * pszRoot)
{
RCODE rc = FERR_OK;
FLMUINT uiIndex = 0;
FLMUINT uiLen = f_strlen( pszPath);
for ( uiIndex = 0; uiIndex < uiLen; uiIndex++)
{
if( pszPath[uiIndex] == '\\')
{
f_strncpy( pszRoot, pszPath, uiIndex + 1);
pszRoot[uiIndex + 1] = '\0';
goto Exit;
}
}
rc = RC_SET( FERR_NOT_FOUND);
pszRoot[0] = '\0';
Exit:
return( rc);
}
/****************************************************************************
Desc:
*****************************************************************************/
FSTATIC void removeChars(
char * pszString,
char cChar)
{
char * pszFrom = pszString;
char * pszTo = pszString;
for ( ;;)
{
if ( *pszFrom != cChar)
{
*pszTo = *pszFrom;
if ( *pszTo)
{
pszTo++;
pszFrom++;
}
else
{
break;
}
}
else
{
pszFrom++;
}
}
}
/****************************************************************************
Desc:
*****************************************************************************/
FSTATIC char * positionToPath(
char * pszCommandLine)
{
char * pszPathBegin = pszCommandLine + f_strlen( pszCommandLine);
if( f_strlen( pszCommandLine) != 0 && *(pszPathBegin - 1) != ASCII_SPACE)
{
if( *(pszPathBegin - 1))
{
// Move to the beginning of the last token
while( (pszPathBegin != pszCommandLine) &&
(*(pszPathBegin - 1) != ASCII_SPACE))
{
if( *(pszPathBegin - 1) == '\"')
{
// Find first whitespace after begin quote
FLMBOOL bInQuotes = TRUE;
pszPathBegin--;
while ( ( pszPathBegin != pszCommandLine) && bInQuotes)
{
pszPathBegin--;
if ( *pszPathBegin == '\"')
{
bInQuotes = FALSE;
}
}
}
else
{
pszPathBegin--;
}
}
}
}
return( pszPathBegin);
}
/****************************************************************************
Desc: Given a path, extract the base directory and a wildcard for searching
*****************************************************************************/
FSTATIC void extractBaseDirAndWildcard(
IF_FileSystem * pFileSystem,
char * pszPath,
char * pszBase,
char * pszWildcard)
{
flmAssert( pszBase && pszWildcard);
pszBase[0] = '\0';
pszWildcard[0] = '\0';
// If the extended directory is a path but does not end with a
// slash, this means that we will use the last portion of the
// path as our search pattern.
if( pszPath &&
f_strchr( pszPath, SLASH) &&
pszPath[ f_strlen( pszPath) - 1] != SLASH)
{
pFileSystem->pathReduce( pszPath, pszBase, pszWildcard);
// Darn thing sometimes removes the trailing slash. Put it back.
if ( pszPath[ f_strlen( pszBase) - 1] != SLASH)
{
f_strcat( pszBase, SSLASH);
}
}
else if ( pszPath && !f_strchr( pszPath, SLASH))
{
// We will assume that what we have is just a part of a filename
// since it contains no slashes.
f_strcpy( pszWildcard, pszPath);
//pszTabCompleteBegin[0] = '\0';
}
else if ( pszPath && pszPath[ f_strlen( pszPath) - 1] == SLASH)
{
// We were given only a path
f_strcpy( pszBase, pszPath);
}
f_strcat( pszWildcard, "*");
}
/***************************************************************************
Desc: Program entry point (main)
****************************************************************************/
#ifdef FLM_RING_ZERO_NLM
extern "C" int nlm_main(
#else
int main(
#endif
int, // iArgC,
char ** // ppszArgV
)
{
RCODE rc = FERR_OK;
FlmShell * pShell = NULL;
if( RC_BAD( rc = FlmStartup()))
{
goto Exit;
}
if( RC_BAD( rc = FTXInit( "FLAIM DB Shell", (FLMBYTE)80, (FLMBYTE)50,
FLM_BLUE, FLM_WHITE, NULL, NULL)))
{
goto Exit;
}
FTXSetShutdownFlag( &gv_bShutdown);
if( (pShell = f_new FlmShell) != NULL)
{
if( RC_OK( pShell->setup()))
{
(void)pShell->execute();
}
}
Exit:
if (pShell)
{
pShell->Release();
}
gv_bShutdown = TRUE;
FTXExit();
FlmShutdown();
return( 0);
}