Ejemplo n.º 1
0
/****************************************************************************
Desc:	All of the fromAscii() functions convert values stored in strings to
      various native formats
****************************************************************************/
void F_IniFile::fromAscii( 
	FLMBOOL *		pbVal, 
	const char *	pszParamValue)
{
	if( f_stricmp( pszParamValue, "true") == 0 ||
		 f_stricmp( pszParamValue, "enabled") == 0 ||
		 f_stricmp( pszParamValue, "on") == 0 ||
		 f_stricmp( pszParamValue, "1") == 0)
	{
		*pbVal = TRUE;
	}
	else
	{
		*pbVal = FALSE;
	}
}
Ejemplo n.º 2
0
/********************************************************************
Desc:	Edit Text
*********************************************************************/
FLMBOOL ViewEditText(
	const char *	pszPrompt,
	char *			pszText,
	FLMUINT			uiTextLen,
	FLMBOOL *		pbValEntered)
{
	char		szTempBuf [100];
	FLMUINT	uiNumCols;
	FLMUINT	uiNumRows;

	f_conGetScreenSize( &uiNumCols, &uiNumRows);
	f_conSetBackFore( FLM_BLACK, FLM_WHITE);
	f_conClearScreen( 0, uiNumRows - 2);
	ViewAskInput( pszPrompt, szTempBuf, sizeof( szTempBuf) - 1);
	f_conSetBackFore( FLM_BLACK, FLM_WHITE);
	f_conClearScreen( 0, uiNumRows - 2);
	
	if (f_stricmp( szTempBuf, "\\") == 0)
	{
		*pbValEntered = FALSE;
		return( FALSE);
	}
	if( !szTempBuf[ 0])
	{
		*pbValEntered = FALSE;
		return( TRUE);
	}
	if (f_strlen( szTempBuf) >= uiTextLen)
	{
		szTempBuf [uiTextLen - 1] = 0;
	}
	f_strcpy( pszText, szTempBuf);
	*pbValEntered = TRUE;
	return( TRUE);
}
Ejemplo n.º 3
0
/****************************************************************************
Desc:	Returns the length of the base part of a database name.  If the
		name ends with a '.' or ".db", this will not be included in the
		returned length.
****************************************************************************/
void flmGetDbBasePath(
	char *			pszBaseDbName,
	const char *	pszDbName,
	FLMUINT *		puiBaseDbNameLen)
{
	FLMUINT			uiBaseLen = f_strlen( pszDbName);

	if( uiBaseLen <= 3 || 
		f_stricmp( &pszDbName[ uiBaseLen - 3], ".db") != 0)
	{
		if( pszDbName[ uiBaseLen - 1] == '.')
		{
			uiBaseLen--;
		}
	}
	else
	{
		uiBaseLen -= 3;
	}

	f_memcpy( pszBaseDbName, pszDbName, uiBaseLen);
	pszBaseDbName[ uiBaseLen] = 0;

	if( puiBaseDbNameLen)
	{
		*puiBaseDbNameLen = uiBaseLen;
	}
}
Ejemplo n.º 4
0
/********************************************************************
Desc:	Get a number from the user
*********************************************************************/
FLMBOOL ViewGetNum(
	const char *	pszPrompt,
	void *			pvNum,
	FLMBOOL			bEnterHexFlag,
	FLMUINT			uiNumBytes,
	FLMUINT64		ui64MaxValue,
	FLMBOOL *		pbValEntered)
{
	FLMBOOL			bOk = FALSE;
	char				szTempBuf[ 20];
	FLMUINT     	uiLoop;
	FLMUINT			uiChar;
	FLMBOOL			bGetOK;
	FLMUINT64		ui64Num;
	FLMUINT			uiMaxDigits;
	FLMUINT			uiNumCols;
	FLMUINT			uiNumRows;

	f_conGetScreenSize( &uiNumCols, &uiNumRows);

	if (bEnterHexFlag)
	{
		uiMaxDigits = uiNumBytes * 2;
	}
	else
	{
		uiMaxDigits = (uiNumBytes == 8
						  ? 20
						  : (uiNumBytes == 4
							  ? 10
							  : (uiNumBytes == 2
								  ? 5
								  : 3)));
	}

	for (;;)
	{
		bGetOK = TRUE;
		f_conSetBackFore( FLM_BLACK, FLM_WHITE);
		f_conClearScreen( 0, uiNumRows - 2);
		ViewAskInput( pszPrompt, szTempBuf, sizeof( szTempBuf));
		f_conSetBackFore( FLM_BLACK, FLM_WHITE);
		f_conClearScreen( 0, uiNumRows - 2);
		if (f_stricmp( szTempBuf, "\\") == 0)
		{
			*pbValEntered = FALSE;
			goto Exit;
		}
		if( !szTempBuf[ 0])
		{
			*pbValEntered = FALSE;
			bOk = TRUE;
			goto Exit;
		}
		uiLoop = 0;
		ui64Num = 0;
		while (szTempBuf[ uiLoop] && uiLoop < uiMaxDigits)
		{
			uiChar = szTempBuf[ uiLoop];
			if (bEnterHexFlag)
			{
				ui64Num <<= 4;
				if (uiChar >= '0' && uiChar <= '9')
				{
					ui64Num += (FLMUINT64)(uiChar - '0');
				}
				else if (uiChar >= 'a' && uiChar <= 'f')
				{
					ui64Num += (FLMUINT64)(uiChar - 'a' + 10);
				}
				else if (uiChar >= 'A' && uiChar <= 'F')
				{
					ui64Num += (FLMUINT64)(uiChar - 'A' + 10);
				}
				else
				{
					ViewShowError(
						"Illegal digit in number - must be hex digits");
					bGetOK = FALSE;
					break;
				}
			}
			else if (uiChar < '0' || uiChar > '9')
			{
				ViewShowError(
					"Illegal digit in number - must be 0 through 9");
				bGetOK = FALSE;
				break;
			}
			else
			{
				if (ui64MaxValue / 10 < ui64Num)
				{
					ViewShowError( "Number is too large");
					bGetOK = FALSE;
					break;
				}
				else
				{
					ui64Num *= 10;
					if (ui64MaxValue - (FLMUINT64)(uiChar - '0') < ui64Num)
					{
						ViewShowError( "Number is too large");
						bGetOK = FALSE;
						break;
					}
					else
					{
						ui64Num += (FLMUINT64)(uiChar - '0');
					}
				}
			}
			uiLoop++;
		}
		if (bGetOK)
		{
			if (uiNumBytes == 8)
			{
				*((FLMUINT64 *)(pvNum)) = ui64Num;
			}
			else if (uiNumBytes == 4)
			{
				*((FLMUINT32 *)(pvNum)) = (FLMUINT32)ui64Num;
			}
			else if( uiNumBytes == 2)
			{
				*((FLMUINT16 *)(pvNum)) = (FLMUINT16)ui64Num;
			}
			else
			{
				*((FLMBYTE *)(pvNum)) = (FLMBYTE)ui64Num;
			}
			*pbValEntered = TRUE;
			bOk = TRUE;
			goto Exit;
		}
	}

Exit:

	return( bOk);
}
Ejemplo n.º 5
0
/********************************************************************
Desc:	Edit binary data
*********************************************************************/
FLMBOOL ViewEditBinary(
	const char *	pszPrompt,
	FLMBYTE *		pucBuf,
	FLMUINT *		puiByteCount,
	FLMBOOL *		pbValEntered)
{
	FLMUINT		uiMaxBytes = *puiByteCount;
	FLMUINT		uiByteCount;
	FLMBOOL		bOdd;
	char			szTempBuf [300];
	FLMUINT		uiLoop;
	FLMUINT		uiNumCols;
	FLMUINT		uiNumRows;

	f_conGetScreenSize( &uiNumCols, &uiNumRows);

	if (!pszPrompt)
	{
		pszPrompt = "Enter Binary Values (in hex): ";
	}
	for (;;)
	{
		f_conSetBackFore( FLM_BLACK, FLM_WHITE);
		f_conClearScreen( 0, uiNumRows - 2);
		ViewAskInput( pszPrompt, szTempBuf, sizeof( szTempBuf));
		f_conSetBackFore( FLM_BLACK, FLM_WHITE);
		f_conClearScreen( 0, uiNumRows - 2);
		if( f_stricmp( szTempBuf, "\\") == 0)
		{
			*pbValEntered = FALSE;
			return( FALSE);
		}
		if (!szTempBuf[ 0])
		{
			*pbValEntered = FALSE;
			return( TRUE);
		}

		bOdd = FALSE;
		uiByteCount = 0;
		uiLoop = 0;
		while (szTempBuf [uiLoop])
		{
			FLMBYTE	ucValue;

			ucValue = szTempBuf [uiLoop];
			if (ucValue >= '0' && ucValue <= '9')
			{
				ucValue -= '0';
			}
			else if (ucValue >= 'a' && ucValue <= 'f')
			{
				ucValue = ucValue - 'a' + 10;
			}
			else if (ucValue >= 'A' && ucValue <= 'F')
			{
				ucValue = ucValue - 'A' + 10;
			}
			else if (ucValue == ' ' || ucValue == '\t')
			{
				bOdd = FALSE;
				uiLoop++;
				continue;
			}
			else
			{
				uiByteCount = 0;
				ViewShowError( "Non-HEX digits are illegal");
				break;
			}

			// If we get here, we have another digit

			if (bOdd)
			{
				bOdd = FALSE;
				(*pucBuf) <<= 4;
				(*pucBuf) |= ucValue;
			}
			else
			{
				if (uiByteCount == uiMaxBytes)
				{
					break;
				}

				// Don't increment pucBuf the first time through

				if (uiByteCount)
				{
					pucBuf++;
				}
				uiByteCount++;
				*pucBuf = ucValue;
				bOdd = TRUE;
			}
			uiLoop++;
		}
		if (!uiByteCount)
		{
			if (!szTempBuf[ uiLoop])
			{
				ViewShowError( "No HEX digits entered");
			}
		}
		else if (szTempBuf[ uiLoop])
		{
			ViewShowError( "Too many digits entered");
		}
		else
		{
			*puiByteCount = uiByteCount;
			*pbValEntered = TRUE;
			return( TRUE);
		}
	}
}
Ejemplo n.º 6
0
/****************************************************************************
Desc:		Renames all files of a database
****************************************************************************/
RCODE F_DbSystem::dbRename(
    const char *			pszDbName,
    // [IN] Database to be renamed.
    const char *			pszDataDir,
    // [IN] Directory for data files.
    const char *			pszRflDir,
    // [IN] RFL directory of database. NULL can be
    // passed to indicate that the log files are located
    // in the same directory as the other database files.
    const char *			pszNewDbName,
    // [IN] New name to be given to the database.  May be
    // the short name only, or include a directory.  If it
    // includes a directory, it must be the same directory
    // as the directory given in pszDbName.
    FLMBOOL					bOverwriteDestOk,
    // [IN] Ok to overwrite existing file with rename?
    IF_DbRenameStatus *	ifpStatus)
// [IN] Status callback function.
{
    RCODE					rc = NE_SFLM_OK;
    FLMUINT				uiFileNumber;
    DBRenameInfo *		pRenameList = NULL;
    FLMBOOL				bFileFound;
    char *				pszOldName = NULL;
    char *				pszNewName;
    char *				pszOldDataName;
    char *				pszNewDataName;
    char *				pszFullNewName;
    char					szOldBase [F_FILENAME_SIZE];
    char					szNewBase [F_FILENAME_SIZE];
    char *				pszExtOld;
    char *				pszExtNew;
    char *				pszDataExtOld;
    char *				pszDataExtNew;

    // Cannot handle empty database name.

    flmAssert( pszDbName && *pszDbName);
    flmAssert( pszNewDbName && *pszNewDbName);

    // Allocate memory for a read buffer, the log header, and various
    // file names.

    if (RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE * 5, &pszOldName)))
    {
        goto Exit;
    }
    pszNewName = pszOldName + F_PATH_MAX_SIZE;
    pszOldDataName = pszNewName + F_PATH_MAX_SIZE;
    pszNewDataName = pszOldDataName + F_PATH_MAX_SIZE;
    pszFullNewName = pszNewDataName + F_PATH_MAX_SIZE;

    // There must be either no directory specified for the new name, or
    // it must be identical to the old directory.

    if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce(
                         pszDbName, pszOldName, szOldBase)))
    {
        goto Exit;
    }
    if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce(
                         pszNewDbName, pszNewName, szNewBase)))
    {
        goto Exit;
    }

    // Directories must be the same.

    if (*pszNewName && f_stricmp( pszOldName, pszNewName) != 0)
    {
        rc = RC_SET( NE_SFLM_INVALID_PARM);
        goto Exit;
    }
    f_strcpy( pszNewName, pszOldName);
    if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathAppend(
                         pszNewName, szNewBase)))
    {
        goto Exit;
    }

    f_strcpy( pszFullNewName, pszNewName);
    f_strcpy( pszOldName, pszDbName);

    if (pszDataDir && *pszDataDir)
    {
        f_strcpy( pszOldDataName, pszDataDir);
        f_strcpy( pszNewDataName, pszDataDir);
        if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathAppend(
                             pszOldDataName, szOldBase)))
        {
            goto Exit;
        }
        if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathAppend(
                             pszNewDataName, szNewBase)))
        {
            goto Exit;
        }
    }
    else
    {
        f_strcpy( pszNewDataName, pszNewName);
        f_strcpy( pszOldDataName, pszOldName);
    }

    // First make sure we have closed the databases and gotten rid of
    // them from our internal memory tables - in case they had been open.

    if (RC_BAD( rc = checkDatabaseClosed( pszDbName, pszDataDir)))
    {
        goto Exit;
    }
    if (RC_BAD( rc = checkDatabaseClosed( pszFullNewName, pszDataDir)))
    {
        goto Exit;
    }

    // Start renaming files, beginning with the main DB file.

    if (RC_BAD( rc = flmRenameFile( pszDbName, pszFullNewName,
                                    bOverwriteDestOk, FALSE,
                                    &pRenameList, &bFileFound,
                                    ifpStatus)))
    {
        goto Exit;
    }

    // Find where the extension of the old and new database names are

    pszExtOld = pszOldName + f_strlen( pszOldName) - 1;
    pszDataExtOld = pszOldDataName + f_strlen( pszOldDataName) - 1;
    while (pszExtOld != pszOldName && *pszExtOld != '.')
    {
        pszExtOld--;

        // Both the old db name and old data name have the same
        // base name, so we can decrement pszDataExtOld
        // at the same time we decrement pszExtOld.

        pszDataExtOld--;
    }
    if (*pszExtOld != '.')
    {
        pszExtOld = pszOldName + f_strlen( pszOldName);
        pszDataExtOld = pszOldDataName + f_strlen( pszOldDataName);
    }

    pszExtNew = pszNewName + f_strlen( pszNewName) - 1;
    pszDataExtNew = pszNewDataName + f_strlen( pszNewDataName) - 1;
    while (pszExtNew != pszOldName && *pszExtNew != '.')
    {
        pszExtNew--;

        // Both the new db name and new data name have the same
        // base name, so we can decrement pszDataExtNew
        // at the same time we decrement pszExtNew.

        pszDataExtNew--;
    }
    if (*pszExtNew != '.')
    {
        pszExtNew = pszNewName + f_strlen( pszNewName);
        pszDataExtNew = pszNewDataName + f_strlen( pszNewDataName);
    }

    // Rename the .lck file, if any.  This is necessary for UNIX.

    f_strcpy( pszExtOld, ".lck");
    f_strcpy( pszExtNew, ".lck");
    if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
                                    bOverwriteDestOk, TRUE,
                                    &pRenameList, &bFileFound,
                                    ifpStatus)))
    {
        goto Exit;
    }

    // Rename block (data) files.

    uiFileNumber = 1;
    for (;;)
    {
        F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszDataExtOld);
        F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszDataExtNew);

        if (RC_BAD( rc = flmRenameFile( pszOldDataName, pszNewDataName,
                                        bOverwriteDestOk, TRUE,
                                        &pRenameList, &bFileFound,
                                        ifpStatus)))
        {
            goto Exit;
        }
        if (!bFileFound)
        {
            break;
        }
        if (uiFileNumber == MAX_DATA_BLOCK_FILE_NUMBER)
        {
            break;
        }
        uiFileNumber++;
    }

    // Rename rollback log files.

    uiFileNumber = FIRST_LOG_BLOCK_FILE_NUMBER;
    for (;;)
    {
        F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszExtOld);
        F_SuperFileClient::bldSuperFileExtension( uiFileNumber, pszExtNew);

        if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
                                        bOverwriteDestOk, TRUE,
                                        &pRenameList, &bFileFound,
                                        ifpStatus)))
        {
            goto Exit;
        }
        if (!bFileFound)
        {
            break;
        }
        if (uiFileNumber == MAX_LOG_BLOCK_FILE_NUMBER)
        {
            break;
        }
        uiFileNumber++;
    }

    // Rename the RFL directory.

    if (RC_BAD( rc = rflGetDirAndPrefix( pszDbName, pszRflDir, pszOldName)))
    {
        goto Exit;
    }

    if (RC_BAD( rc = rflGetDirAndPrefix( pszFullNewName, pszRflDir,
                                         pszNewName)))
    {
        goto Exit;
    }

    if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
                                    bOverwriteDestOk, TRUE,
                                    &pRenameList, &bFileFound,
                                    ifpStatus)))
    {
        goto Exit;
    }

Exit:
    if (pszOldName)
    {
        f_free( &pszOldName);
    }

    // Free the list of renamed files.

    while (pRenameList)
    {
        DBRenameInfo *		pRenameFile;

        pRenameFile = pRenameList;
        pRenameList = pRenameList->pNext;

        // If we had an error of some sort, attempt to un-rename
        // the file that had been renamed.

        if (RC_BAD( rc))
        {
            gv_SFlmSysData.pFileSystem->renameFile(
                pRenameFile->Info.szDstFileName, pRenameFile->Info.szSrcFileName);
        }
        f_free( &pRenameFile);
    }
    return( rc);
}
Ejemplo n.º 7
0
/****************************************************************************
Desc:	Rename a database file and add to list of renamed files.
****************************************************************************/
FSTATIC RCODE flmRenameFile(
    const char *			pszSrcFileName,
    const char *			pszDstFileName,
    FLMBOOL					bOverwriteDestOk,
    FLMBOOL					bPathNotFoundOk,
    DBRenameInfo **		ppRenameList,
    FLMBOOL *				pbFileFound,
    IF_DbRenameStatus *	ifpStatus)
{
    RCODE				rc = NE_SFLM_OK;
    DBRenameInfo *	pRenameFile = NULL;

    *pbFileFound = FALSE;

    // Should not do anything if the source and destination names
    // are the same.

    if (f_stricmp( pszSrcFileName, pszDstFileName) == 0)
    {
        if (gv_SFlmSysData.pFileSystem->doesFileExist(
                    pszSrcFileName) == NE_SFLM_OK)
        {
            *pbFileFound = TRUE;
        }
        goto Exit;
    }

    if (RC_BAD( rc = f_alloc( sizeof( DBRenameInfo), &pRenameFile)))
    {
        goto Exit;
    }

    // If a destination file exists, and it is OK to overwrite
    // it, it must be deleted.

    if (bOverwriteDestOk)
    {
        if (gv_SFlmSysData.pFileSystem->isDir( pszDstFileName))
        {
            if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->removeDir(
                                 pszDstFileName, TRUE)))
            {
                goto Exit;
            }
        }
        else
        {
            if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->deleteFile(
                                 pszDstFileName)))
            {
                if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME)
                {
                    rc = NE_SFLM_OK;
                }
                else
                {
                    goto Exit;
                }
            }
        }
    }

    // If names are the same, no need to actually do the
    // rename.

    if (RC_BAD( rc = gv_SFlmSysData.pFileSystem->renameFile(
                         pszSrcFileName, pszDstFileName)))
    {
        if (rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME)
        {
            if (bPathNotFoundOk)
            {
                rc = NE_SFLM_OK;
            }
            else
            {
                goto Exit;
            }
        }
        else
        {
            goto Exit;
        }
    }
    else
    {
        *pbFileFound = TRUE;
        pRenameFile->pNext = *ppRenameList;
        *ppRenameList = pRenameFile;

        // Do user callback.  User could choose to stop the rename
        // from continuing.
        if (ifpStatus)
        {
            f_strcpy( pRenameFile->Info.szSrcFileName, pszSrcFileName);
            f_strcpy( pRenameFile->Info.szDstFileName, pszDstFileName);
            if (RC_BAD( rc = ifpStatus->dbRenameStatus(
                                 pRenameFile->Info.szSrcFileName,
                                 pRenameFile->Info.szDstFileName)))
            {
                goto Exit;
            }
        }

        // So it won't get deallocated at exit.

        pRenameFile = NULL;
    }
Exit:
    if (pRenameFile)
    {
        f_free( &pRenameFile);
    }
    return( rc);
}
Ejemplo n.º 8
0
/****************************************************************************
Desc:		This routine is used to see if a file is already in use somewhere.
			This is only called for files which are opened directly by the
			application.
Notes:	This routine assumes that the global mutex is locked, but it
			may unlock and re-lock the mutex if needed.
****************************************************************************/
RCODE F_DbSystem::findDatabase(
	const char *	pszDbPath,
	const char *	pszDataDir,
	F_Database **	ppDatabase)
{
	RCODE				rc = NE_XFLM_OK;
	F_BUCKET *		pBucket;
	FLMUINT			uiBucket;
	FLMBOOL			bMutexLocked = TRUE;
	F_Database *	pDatabase;
	char				szDbPathStr1 [F_PATH_MAX_SIZE];
	char				szDbPathStr2 [F_PATH_MAX_SIZE];
	F_SEM				hWaitSem = F_SEM_NULL;

	*ppDatabase = NULL;

	// Normalize the path to a string before looking for it.
	// NOTE: On non-UNIX, non-WIN platforms, this will basically convert
	// the string to upper case.

	if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString( 
		pszDbPath, szDbPathStr1)))
	{
		goto Exit;
	}

Retry:

	*ppDatabase = NULL;

	if( !bMutexLocked)
	{
		f_mutexLock( gv_XFlmSysData.hShareMutex);
		bMutexLocked = TRUE;
	}

	pBucket = gv_XFlmSysData.pDatabaseHashTbl;
	uiBucket = f_strHashBucket( szDbPathStr1, pBucket, FILE_HASH_ENTRIES);
	pDatabase = (F_Database *)pBucket [uiBucket].pFirstInBucket;
	while (pDatabase)
	{
		// Compare the strings.  On non-Unix platforms we must use
		// f_stricmp, because case does not matter for file names
		// on those platforms.

#ifdef FLM_UNIX
		if( f_strcmp( szDbPathStr1, pDatabase->m_pszDbPath) == 0)
#else
		if( f_stricmp( szDbPathStr1, pDatabase->m_pszDbPath) == 0)
#endif
		{

			// Make sure data paths match.

			if (pszDataDir && *pszDataDir)
			{
				if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString(
					pszDataDir, szDbPathStr2)))
				{
					goto Exit;
				}
				
				if (pDatabase->m_pszDataDir)
				{
					// f_stricmp must be used on non-unix platforms because file
					// names are case insensitive on those platforms.
#ifdef FLM_UNIX
					if (f_strcmp( pDatabase->m_pszDataDir, szDbPathStr2) != 0)
#else
					if (f_stricmp( pDatabase->m_pszDataDir, szDbPathStr2) != 0)
#endif
					{
						rc = RC_SET( NE_XFLM_DATA_PATH_MISMATCH);
						goto Exit;
					}
				}
				else
				{
					rc = RC_SET( NE_XFLM_DATA_PATH_MISMATCH);
					goto Exit;
				}
			}
			else if (pDatabase->m_pszDataDir)
			{
				rc = RC_SET( NE_XFLM_DATA_PATH_MISMATCH);
				goto Exit;
			}
			*ppDatabase = pDatabase;
			break;
		}
		pDatabase = pDatabase->m_pNext;
	}

	if (*ppDatabase && pDatabase->m_uiFlags & DBF_BEING_CLOSED)
	{
		if( RC_BAD( rc = f_semCreate( &hWaitSem)))
		{
			goto Exit;
		}
		
		// Put ourselves into the notify list and then re-try
		// the lookup when we wake up

		if (RC_BAD( rc = f_notifyWait( gv_XFlmSysData.hShareMutex, hWaitSem,
			NULL, &pDatabase->m_pCloseNotifies)))
		{
			goto Exit;
		}
		
		f_semDestroy( &hWaitSem);

		// The mutex will be locked at this point.  Re-try the lookup.
		// IMPORTANT NOTE: pDatabase will have been destroyed by this
		// time.  DO NOT use it for anything!

		goto Retry;
	}

Exit:

	if( hWaitSem != F_SEM_NULL)
	{
		f_semDestroy( &hWaitSem);
	}

	// Make sure the global mutex is re-locked before exiting

	if( !bMutexLocked)
	{
		f_mutexLock( gv_XFlmSysData.hShareMutex);
	}
	

	return( rc);
}
Ejemplo n.º 9
0
/*******************************************************************************
Desc:	Renames a database
*******************************************************************************/
FLMEXP RCODE FLMAPI FlmDbRename(
	const char *		pszDbName,
	const char *		pszDataDir,
	const char *		pszRflDir,
	const char *		pszNewDbName,
	FLMBOOL				bOverwriteDestOk,
	STATUS_HOOK			fnStatusCallback,
	void *				UserData)
{
	RCODE					rc = FERR_OK;
	IF_FileHdl *		pFileHdl = NULL;
	FLMUINT				uiFileNumber;
	FILE_HDR				FileHdr;
	LOG_HDR				LogHdr;
	DBRenameInfo *		pRenameList = NULL;
	FLMBOOL				bFileFound;
	FLMBYTE *			pucBuffer = NULL;
	FLMBYTE *			pucLogHdr;
	char *				pszOldName;
	char *				pszNewName;
	char *				pszOldDataName;
	char *				pszNewDataName;
	char *				pszFullNewName;
	char					szOldBase[ F_FILENAME_SIZE];
	char					szNewBase[ F_FILENAME_SIZE];
	char *				pszExtOld;
	char *				pszExtNew;
	char *				pszDataExtOld;
	char *				pszDataExtNew;

	// Cannot handle empty database name.

	flmAssert( pszDbName && *pszDbName);
	flmAssert( pszNewDbName && *pszNewDbName);

	// Allocate memory for a read buffer, the log header, and various
	// file names.

	if( RC_BAD( rc = f_allocAlignedBuffer( 
		2048 + LOG_HEADER_SIZE + F_PATH_MAX_SIZE * 5, &pucBuffer)))
	{
		goto Exit;
	}
	pucLogHdr = pucBuffer + 2048;
	pszOldName = (char *)(pucLogHdr + LOG_HEADER_SIZE);
	pszNewName = pszOldName + F_PATH_MAX_SIZE;
	pszOldDataName = pszNewName + F_PATH_MAX_SIZE;
	pszNewDataName = pszOldDataName + F_PATH_MAX_SIZE;
	pszFullNewName = pszNewDataName + F_PATH_MAX_SIZE;

	// There must be either no directory specified for the new name, or
	// it must be identical to the old directory.

	if (RC_BAD( rc = gv_FlmSysData.pFileSystem->pathReduce( 
		pszDbName, pszOldName, szOldBase)))
	{
		goto Exit;
	}
	
	if (RC_BAD( rc = gv_FlmSysData.pFileSystem->pathReduce( 
		pszNewDbName, pszNewName, szNewBase)))
	{
		goto Exit;
	}

	// Directories must be the same.

	if (*pszNewName && f_stricmp( pszOldName, pszNewName) != 0)
	{
		rc = RC_SET( FERR_INVALID_PARM);
		goto Exit;
	}
	
	f_strcpy( pszNewName, pszOldName);
	
	if (RC_BAD( rc = gv_FlmSysData.pFileSystem->pathAppend( 
		pszNewName, szNewBase)))
	{
		goto Exit;
	}

	f_strcpy( pszFullNewName, pszNewName);
	f_strcpy( pszOldName, pszDbName);

	if( pszDataDir && *pszDataDir)
	{
		f_strcpy( pszOldDataName, pszDataDir);
		f_strcpy( pszNewDataName, pszDataDir);
		
		if (RC_BAD( rc = gv_FlmSysData.pFileSystem->pathAppend( 
			pszOldDataName, szOldBase)))
		{
			goto Exit;
		}
		
		if (RC_BAD( rc = gv_FlmSysData.pFileSystem->pathAppend( 
			pszNewDataName, szNewBase)))
		{
			goto Exit;
		}
	}
	else
	{
		f_strcpy( pszNewDataName, pszNewName);
		f_strcpy( pszOldDataName, pszOldName);
	}

	// First make sure we have closed the databases and gotten rid of
	// them from our internal memory tables - in case they had been open.

	if( RC_BAD( rc = FlmConfig( FLM_CLOSE_FILE, 
		(void *)pszDbName, (void *)pszDataDir)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = FlmConfig( FLM_CLOSE_FILE, 
		(void *)pszFullNewName, (void *)pszDataDir)))
	{
		goto Exit;
	}
	
	gv_FlmSysData.pFileHdlCache->closeUnusedFiles();

	// Open the file so we can get the log header.

	if( RC_BAD( rc = gv_FlmSysData.pFileSystem->openFile( pszDbName, 
		gv_FlmSysData.uiFileOpenFlags, &pFileHdl)))
	{
		goto Exit;
	}

	// Read the header to get the low and high RFL log
	// file numbers.

	if (RC_BAD( flmReadAndVerifyHdrInfo( NULL, pFileHdl,
								pucBuffer, &FileHdr, &LogHdr, pucLogHdr)))
	{
		goto Exit;
	}

	// Close the file.

	pFileHdl->Release();
	pFileHdl = NULL;

	// Start renaming files, beginning with the main DB file.

	if( RC_BAD( rc = flmRenameFile( pszDbName, pszFullNewName,
								bOverwriteDestOk, FALSE,
								&pRenameList, &bFileFound,
								fnStatusCallback, UserData)))
	{
		goto Exit;
	}

	// Find where the extension of the old and new database names are

	pszExtOld = pszOldName + f_strlen( pszOldName) - 1;
	pszDataExtOld = pszOldDataName + f_strlen( pszOldDataName) - 1;
	while (pszExtOld != pszOldName && *pszExtOld != '.')
	{
		pszExtOld--;

		// Both the old db name and old data name have the same
		// base name, so we can decrement pszDataExtOld
		// at the same time we decrement pszExtOld.

		pszDataExtOld--;
	}
	
	if (*pszExtOld != '.')
	{
		pszExtOld = pszOldName + f_strlen( pszOldName);
		pszDataExtOld = pszOldDataName + f_strlen( pszOldDataName);
	}

	pszExtNew = pszNewName + f_strlen( pszNewName) - 1;
	pszDataExtNew = pszNewDataName + f_strlen( pszNewDataName) - 1;
	
	while (pszExtNew != pszOldName && *pszExtNew != '.')
	{
		pszExtNew--;

		// Both the new db name and new data name have the same
		// base name, so we can decrement pszDataExtNew
		// at the same time we decrement pszExtNew.

		pszDataExtNew--;
	}
	
	if (*pszExtNew != '.')
	{
		pszExtNew = pszNewName + f_strlen( pszNewName);
		pszDataExtNew = pszNewDataName + f_strlen( pszNewDataName);
	}

	// Rename the .lck file, if any.  This is necessary for UNIX.

	f_strcpy( pszExtOld, ".lck");
	f_strcpy( pszExtNew, ".lck");
	if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
								bOverwriteDestOk, TRUE,
								&pRenameList, &bFileFound,
								fnStatusCallback, UserData)))
	{
		goto Exit;
	}

	// Rename block (data) files.

	uiFileNumber = 1;
	for (;;)
	{
		F_SuperFileClient::bldSuperFileExtension( FileHdr.uiVersionNum,
			uiFileNumber, pszDataExtOld);
		F_SuperFileClient::bldSuperFileExtension( FileHdr.uiVersionNum,
			uiFileNumber, pszDataExtNew);

		if (RC_BAD( rc = flmRenameFile( pszOldDataName, pszNewDataName,
									bOverwriteDestOk, TRUE,
									&pRenameList, &bFileFound,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
		if (!bFileFound)
		{
			break;
		}
		if (uiFileNumber ==
				MAX_DATA_BLOCK_FILE_NUMBER( FileHdr.uiVersionNum))
		{
			break;
		}
		uiFileNumber++;
	}

	// Rename rollback log files.

	uiFileNumber =
			FIRST_LOG_BLOCK_FILE_NUMBER (FileHdr.uiVersionNum);
	for (;;)
	{
		F_SuperFileClient::bldSuperFileExtension( FileHdr.uiVersionNum,
			uiFileNumber, pszExtOld);
		F_SuperFileClient::bldSuperFileExtension( FileHdr.uiVersionNum,
			uiFileNumber, pszExtNew);

		if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
									bOverwriteDestOk, TRUE,
									&pRenameList, &bFileFound,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
		
		if (!bFileFound)
		{
			break;
		}
		
		if (uiFileNumber ==
				MAX_LOG_BLOCK_FILE_NUMBER( FileHdr.uiVersionNum))
		{
			break;
		}
		
		uiFileNumber++;
	}

	// Rename roll-forward log files.

	if (FileHdr.uiVersionNum < FLM_FILE_FORMAT_VER_4_3)
	{

		// For pre-4.3 versions, only need to rename one RFL file.

		if (RC_BAD( rc = rflGetFileName( FileHdr.uiVersionNum,
									pszDbName, pszRflDir, 1, pszOldName)))
		{
			goto Exit;
		}
		if (RC_BAD( rc = rflGetFileName( FileHdr.uiVersionNum,
									pszFullNewName, pszRflDir, 1, pszNewName)))
		{
			goto Exit;
		}
		if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
									bOverwriteDestOk, TRUE,
									&pRenameList, &bFileFound,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
	}
	else
	{

		// For 4.3 and greater, rename the RFL directory.

		if (RC_BAD( rc = rflGetDirAndPrefix( FileHdr.uiVersionNum,
									pszDbName, pszRflDir, pszOldName, szOldBase)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = rflGetDirAndPrefix( FileHdr.uiVersionNum,
									pszFullNewName, pszRflDir, pszNewName,
									szNewBase)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = flmRenameFile( pszOldName, pszNewName,
									bOverwriteDestOk, TRUE,
									&pRenameList, &bFileFound,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
	}

Exit:

	if( pFileHdl)
	{
		pFileHdl->Release();
	}
	
	if( pucBuffer)
	{
		f_freeAlignedBuffer( &pucBuffer);
	}

	// Free the list of renamed files.

	while( pRenameList)
	{
		DBRenameInfo *		pRenameFile;

		pRenameFile = pRenameList;
		pRenameList = pRenameList->pNext;

		// If we had an error of some sort, attempt to un-rename
		// the file that had been renamed.

		if (RC_BAD( rc))
		{
			gv_FlmSysData.pFileSystem->renameFile( 
				pRenameFile->Info.szDstFileName, pRenameFile->Info.szSrcFileName);
		}
		
		f_free( &pRenameFile);
	}
	
	return( rc);
}
Ejemplo n.º 10
0
/****************************************************************************
 Desc:	This function handle the details of extracting the parameters
			needed to interpret the request and then generating the response
			HTML page
 ****************************************************************************/
RCODE F_FFilePage::display(
	FLMUINT			uiNumParams,
	const char ** 	ppszParams)
{
	RCODE				rc = FERR_OK;
#define GENERIC_SIZE_B 20
	char				szFrom[ GENERIC_SIZE_B];
	char				szBucket[ 4];
	FLMUINT			uiBucket;
	FFILE				localFFile;
	FFILE *			pFile;
	FLMBOOL			bRefresh;
	void *			pvAddress;
	char				szAddress[GENERIC_SIZE_B];
	char				szLink[GENERIC_SIZE_B];
	FLMBOOL			bFlmLocked = FALSE;
	DATASTRUCT		DataStruct;
	FLMBYTE *		pszTemp = NULL;
	FLMBYTE *		pszTemp1 = NULL;

	if( RC_BAD( rc = f_alloc( 150, &pszTemp)))
	{
		printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 150, &pszTemp1)))
	{
		printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
		goto Exit;
	}

	// Initialize a few variables first...
	szFrom[0] = '\0';
	szBucket[0] = '\0';

	pFile = NULL;

	
	// Get the "From" parameter.  We use this to determine everything else.
	if (RC_BAD( rc = ExtractParameter( uiNumParams,
												  ppszParams,
												  "From",
												  sizeof( szFrom),
												  szFrom)))
	{
		goto Exit;
	}
	
	f_mutexLock( gv_FlmSysData.hShareMutex);
	bFlmLocked = TRUE;


	if (!f_stricmp( szFrom, "FileHashTbl"))
	{

		//  Get the hash bucket index
		if (RC_BAD( rc = ExtractParameter( uiNumParams, 
													 ppszParams, 
													 "Bucket", 
													 sizeof( szBucket),
													 szBucket)))
		{
			goto Exit;
		}

		uiBucket = f_atoud( szBucket);
		pFile = (FFILE *)gv_FlmSysData.pFileHashTbl[uiBucket].pFirstInBucket;
	}
	else if ( (f_stricmp( szFrom, "SCacheBlock") == 0) || 
				 (f_stricmp( szFrom, "RCache") == 0) ||
				 (f_stricmp( szFrom, "FDB") == 0))
	{
		// Get the FFile address and the Hash Bucket
		if (RC_BAD( rc = ExtractParameter( uiNumParams,
													  ppszParams,
													  "Bucket",
													  sizeof( szBucket),
													  szBucket)))
		{
			goto Exit;
		}
		
		uiBucket = f_atoud( szBucket);
		if (RC_BAD( rc = ExtractParameter( uiNumParams,
													  ppszParams,
													  "Address",
													  sizeof( szAddress),
													  szAddress)))
		{
			goto Exit;
		}
		
		pvAddress = (void *)f_atoud( szAddress);

		pFile = (FFILE *)gv_FlmSysData.pFileHashTbl[uiBucket].pFirstInBucket;

		while (pFile && (void *)pFile != pvAddress)
		{
			pFile = pFile->pNext;
		}
		
	}
	else if (f_stricmp( szFrom, "FlmSysData") == 0)
	{
		// Get the Link and the FFile address
		if (RC_BAD( rc = ExtractParameter( uiNumParams,
													  ppszParams,
													  "Link",
													  sizeof( szLink),
													  szLink)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = ExtractParameter( uiNumParams,
													  ppszParams,
													  "Address",
													  sizeof( szAddress),
													  szAddress)))
		{
			goto Exit;
		}
		
		pvAddress = (void *)f_atoud( szAddress);

		if (f_stricmp( szLink, "pMrnuFile") == 0)
		{
			pFile = gv_FlmSysData.pMrnuFile;
			
			// Now let's make sure we are looking at the right FFile...
			while (pFile && (void *)pFile != pvAddress)
			{
				pFile = pFile->pNextNUFile;
			}
		}
		else if (f_stricmp( szLink, "pLrnuFile") == 0)
		{
			pFile = gv_FlmSysData.pLrnuFile;

			// Now let's make sure we are looking at the right FFile...
			while (pFile && (void *)pFile != pvAddress)
			{
				pFile = pFile->pPrevNUFile;
			}
		}

	}
	else if (f_stricmp( szFrom, "FFile") == 0)
	{
		// We need to get the Link, Bucket & Address

		if (RC_BAD(rc = ExtractParameter( uiNumParams,
													 ppszParams,
													 "Link",
													 sizeof( szLink),
													 szLink)))
		{
			goto Exit;
		}

		if (RC_BAD(rc = ExtractParameter( uiNumParams,
													 ppszParams,
													 "Address",
													 sizeof( szAddress),
													 szAddress)))
		{
			goto Exit;
		}
		
		pvAddress = (void *)f_atoud( szAddress);

		if (RC_BAD(rc = ExtractParameter( uiNumParams,
													 ppszParams,
													 "Bucket",
													 sizeof( szBucket),
													 szBucket)))
		{
			goto Exit;
		}

		uiBucket = f_atoud( szBucket);

		// First, let's get a reference to an FFile from the specified bucket

		if (gv_FlmSysData.pFileHashTbl[uiBucket].pFirstInBucket)
		{
			pFile = (FFILE *)gv_FlmSysData.pFileHashTbl[uiBucket].pFirstInBucket;
		}

		// Now let's make sure we are looking at the right FFile...
		while (pFile && (void *)pFile != pvAddress)
		{
			pFile = pFile->pNext;
		}


		// Now what link are we supposed to follow?
		if (f_stricmp( szLink, "pNext") == 0)
		{
			pFile = pFile->pNext;
		}
		else if (f_stricmp( szLink, "pPrev") == 0)
		{
			pFile = pFile->pPrev;
		}
		else if (f_stricmp( szLink, "pNextNUFile") == 0)
		{
			pFile = pFile->pNextNUFile;
		}
		else if (f_stricmp( szLink, "pPrevNUFile") == 0)
		{
			pFile = pFile->pPrevNUFile;
		}

	}

	// Gather additional data if present. Initialize the structure before
	// using it.
	f_memset( &DataStruct, 0, sizeof(DataStruct));

	if (pFile)
	{
		f_memcpy( &localFFile, pFile, sizeof(localFFile));

		if (pFile->pSCacheList)
		{
			DataStruct.SCacheBlkAddress = pFile->pSCacheList->uiBlkAddress;
			DataStruct.SCacheLowTransID = scaGetLowTransID( pFile->pSCacheList),
			DataStruct.SCacheHighTransID = pFile->pSCacheList->uiHighTransID;
		}
		if (pFile->pPendingWriteList)
		{
			DataStruct.PendingWriteBlkAddress = pFile->pPendingWriteList->uiBlkAddress;
			DataStruct.PendingWriteLowTransID = scaGetLowTransID( pFile->pPendingWriteList),
			DataStruct.PendingWriteHighTransID = pFile->pPendingWriteList->uiHighTransID;
		}
		if (pFile->pLastDirtyBlk)
		{
			DataStruct.LastDirtyBlkAddress = pFile->pLastDirtyBlk->uiBlkAddress;
			DataStruct.LastDirtyLowTransID = scaGetLowTransID( pFile->pLastDirtyBlk),
			DataStruct.LastDirtyHighTransID = pFile->pLastDirtyBlk->uiHighTransID;
		}
		
		if (pFile->pFirstRecord)
		{
			DataStruct.FirstRecordContainer = pFile->pFirstRecord->uiContainer;
			DataStruct.FirstRecordDrn = pFile->pFirstRecord->uiDrn;
			DataStruct.FirstRecordLowTransId = pFile->pFirstRecord->uiLowTransId;
		}

		if (pFile->pLastRecord)
		{
			DataStruct.LastRecordContainer = pFile->pLastRecord->uiContainer;
			DataStruct.LastRecordDrn = pFile->pLastRecord->uiDrn;
			DataStruct.LastRecordLowTransId = pFile->pLastRecord->uiLowTransId;
		}
	}
	

	f_mutexUnlock( gv_FlmSysData.hShareMutex);
	bFlmLocked = FALSE;

	stdHdr();

	fnPrintf( m_pHRequest, HTML_DOCTYPE);
	fnPrintf( m_pHRequest,  "<html>\n");


	// Determine if we are being requested to refresh this page or  not.
	if ((bRefresh = DetectParameter( uiNumParams,
											   ppszParams,
											   "Refresh")) == TRUE)
	{
		// Send back the page with a refresh command in the header
		f_sprintf( (char *)pszTemp, "%s/FFile?Refresh&From=%s&Bucket=%s",
					m_pszURLString,
					szFrom, szBucket);

		fnPrintf( m_pHRequest, 
			"<HEAD>"
			"<META http-equiv=\"refresh\" content=\"5; url=%s\">"
			"<TITLE>FFile Structure</TITLE>\n", pszTemp);
	}
	else
	{
		fnPrintf( m_pHRequest, "<HEAD><TITLE>FFile Structure</TITLE>\n");
	}
	printStyle();
	fnPrintf( m_pHRequest, "</HEAD>\n");

	fnPrintf( m_pHRequest,  "<body>\n");

	// If we are not to refresh this page, then don't include the
	// refresh meta command
	if (!bRefresh)
	{
		f_sprintf( (char *)pszTemp,
					"<A HREF=%s/FFile?Refresh&From=%s&Bucket=%s>Start Auto-refresh (5 sec.)</A>",
					m_pszURLString, szFrom, szBucket);
	}
	else
	{
		f_sprintf( (char *)pszTemp,
               "<A HREF=%s/FFile?From=%s&Bucket=%s>Stop Auto-refresh</A>",
					m_pszURLString, szFrom, szBucket);
	}
	// Prepare the refresh link.
	f_sprintf( (char *)pszTemp1,
            "<A HREF=%s/FFile?From=%s&Bucket=%s>Refresh</A>",
				m_pszURLString, szFrom, szBucket);



	// Show the table headings and the refresh option.

	if (pFile)
	{
		// Write out the table headings
		printTableStart( "FFile Structure", 4, 100);

		printTableRowStart();
		printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
		fnPrintf( m_pHRequest, "%s, ", pszTemp1);
		fnPrintf( m_pHRequest, "%s\n", pszTemp);
		printColumnHeadingClose();
		printTableRowEnd();

		// Write out the table headings.
		printTableRowStart();
		printColumnHeading( "Byte Offset (hex)");
		printColumnHeading( "Field Name");
		printColumnHeading( "Field Type");
		printColumnHeading( "Value");
		printTableRowEnd();

		write_data( (pFile ? &localFFile: NULL), (void *)pFile, &DataStruct);

	}
	else
	{
		// Write out an error page...
		fnPrintf( m_pHRequest, 
			"<P>Unable to find the FFile structure that you requested."
			"  This is probably because the state of the cache changed between "
			"the time that you displayed the previous page and the time that you "
			"clicked on the link that brought you here.\n"
			"<P>Click on your browser's \"Back\" button, then click \"Reload\" "
			"and then try the link again.\n");
	}


	fnPrintf( m_pHRequest,  "</body></html>\n");

	fnEmit();

Exit:

	if (bFlmLocked)
	{
		f_mutexUnlock( gv_FlmSysData.hShareMutex);
		bFlmLocked = FALSE;
	}

	if (pszTemp)
	{
		f_free( &pszTemp);
	}

	if (pszTemp1)
	{
		f_free( &pszTemp1);
	}

	return( rc);


}
Ejemplo n.º 11
0
/********************************************************************
Desc: ?
*********************************************************************/
FLMINT ViewGetKey( void)
{
	RCODE				rc = FERR_OK;
	FlmRecord *		pKey = NULL;
	void *			pvFld;
	char				Prompt [80];
	FLMUINT			Num;
	FLMUINT			ValEntered;
	FLMUINT			Len;
	char				TempBuf [80];
	FLMUINT			NumFields;
	FLMUINT			i;
	FLMINT			GetOK;
	FLMBYTE			FieldName [80];
	FLMBYTE			FieldType [16];
	FLMINT			KeyEntered = FALSE;
	FLMBYTE			LFH[ LFH_SIZE];
	FLMUINT			FileOffset;
	LFILE *			pLFile = NULL;
	IXD *				pIxd;
	IFD *				pIfd;
	FLMUINT			uiRootBlkAddress;
	FLMBOOL			bTruncated;

	if (!gv_bViewHdrRead)
		ViewReadHdr();

	/* See if we can get dictionary information. */

	ViewGetDictInfo();
	if (gv_bViewHaveDictInfo)
	{

		/* Find the logical file */

		if ((RC_BAD( fdictGetIndex( ((FDB *)gv_hViewDb)->pDict,
				((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
				gv_uiViewSearchLfNum, &pLFile, NULL))) &&
				(RC_BAD( fdictGetContainer( ((FDB *)gv_hViewDb)->pDict, 
				gv_uiViewSearchLfNum, &pLFile))))
		{
			pLFile = NULL;
		}
	}

	/* See if we have a valid logical file */

	if ((gv_uiViewSearchLfNum == FLM_DATA_CONTAINER) ||
			(gv_uiViewSearchLfNum == FLM_DICT_CONTAINER) ||
			(pLFile))
	{

		/* Get the LFH information for the logical file */

		if (!ViewGetLFH( gv_uiViewSearchLfNum, LFH, &FileOffset))
		{
			ViewShowError( "Could not get LFH for logical file");
			return( FALSE);
		}
		uiRootBlkAddress = FB2UD( &LFH [LFH_ROOT_BLK_OFFSET]);

		if (uiRootBlkAddress == 0xFFFFFFFF)
		{
			ViewShowError( "Logical file is empty");
			return( FALSE);
		}
	}
	else
	{
		ViewShowError( "Logical file not defined");
		return( FALSE);
	}

	if ((gv_uiViewSearchLfNum == FLM_DATA_CONTAINER) ||
		 (gv_uiViewSearchLfNum == FLM_DICT_CONTAINER) ||
		 ((pLFile) &&
		  (pLFile->uiLfType == LF_CONTAINER)))
	{
		if (gv_uiViewSearchLfNum == FLM_DICT_CONTAINER)
			f_strcpy( TempBuf, "Enter Dictionary Record Number: ");
		else if (gv_uiViewSearchLfNum == FLM_DATA_CONTAINER)
			f_strcpy( TempBuf, "Enter Data Container Record Number: ");
		else
			f_sprintf( (char *)TempBuf, 
				"Enter Record Number For Container %u: ", 
				(unsigned)gv_uiViewSearchLfNum);
		if ((!ViewGetNum( TempBuf, &Num, FALSE, 4,
										 0xFFFFFFFF, &ValEntered)) ||
				(!ValEntered))
			return( FALSE);
		f_UINT32ToBigEndian( (FLMUINT32)Num, gv_ucViewSearchKey);
		gv_uiViewSearchKeyLen = 4;
		return( TRUE);
	}

	/* At this point, we are dealing with an index. */

	if (gv_uiViewSearchLfNum == FLM_DICT_INDEX)
	{
		FLMUINT	 wTagType = 0;
		FLMUINT	 wElmLen;

		while (!wTagType)
		{
			if ((!ViewEditText( "Enter Type:", 
									TempBuf, sizeof( TempBuf), &ValEntered)) ||
				 (!ValEntered))
				return( FALSE);
			else if ((f_stricmp( TempBuf, "F") == 0) ||
						(f_stricmp( TempBuf, "FIELD") == 0))
			{
				wTagType = FLM_FIELD_TAG;
			}
			else if ((f_stricmp( TempBuf, "I") == 0) ||
						(f_stricmp( TempBuf, "INDEX") == 0))
			{
				wTagType = FLM_INDEX_TAG;
			}
			else if ((f_stricmp( TempBuf, "C") == 0) ||
						(f_stricmp( TempBuf, "CONTAINER") == 0))
			{
				wTagType = FLM_CONTAINER_TAG;
			}
			else if ((f_stricmp( TempBuf, "A") == 0) ||
						(f_stricmp( TempBuf, "AREA") == 0))
			{
				wTagType = FLM_AREA_TAG;
			}
			else
			{
				ViewShowError( "Illegal type, must be F)ield, I)ndex, C)ontainer, R)ecord, or A)rea");
				wTagType = 0;
			}
		}
		gv_ucViewSearchKey [0] = KY_CONTEXT_PREFIX;
		f_UINT16ToBigEndian( (FLMUINT16)wTagType, &gv_ucViewSearchKey [1]);
		gv_uiViewSearchKeyLen += KY_CONTEXT_LEN;
		gv_ucViewSearchKey [gv_uiViewSearchKeyLen++] = COMPOUND_MARKER;

		if (!ViewEditText( "Enter Name:", TempBuf, sizeof( TempBuf), &ValEntered))
			return( FALSE);

		/* Collate the name. */

		wElmLen = MAX_KEY_SIZ - gv_uiViewSearchKeyLen;
		if (RC_BAD( rc = KYCollateValue( &gv_ucViewSearchKey [gv_uiViewSearchKeyLen],
									&wElmLen,
									(const FLMBYTE *)TempBuf,
									(FLMUINT)f_strlen( TempBuf), FLM_TEXT_TYPE,
									MAX_KEY_SIZ,
									NULL, NULL,
									gv_ViewHdrInfo.FileHdr.uiDefaultLanguage,
									FALSE, FALSE, FALSE, &bTruncated)))
		{
			ViewShowRCError( "collating name", rc);
			return( FALSE);
		}
		gv_uiViewSearchKeyLen += wElmLen;
		return( TRUE);
	}
	else if (!pLFile)
	{
		ViewShowError( "Cannot get logical file information");
		return( FALSE);
	}
	else if (RC_BAD( fdictGetIndex( ((FDB *)gv_hViewDb)->pDict,
			((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
			gv_uiViewSearchLfNum, &pLFile, &pIxd)))
	{
		ViewShowError( "Cannot get index field information");
		return( FALSE);
	}
	else
	{
		pIfd = pIxd->pFirstIfd;
		NumFields = pIxd->uiNumFlds;

		if (!(pIfd->uiFlags & IFD_COMPOUND))
		{
			NumFields = 1;
		}

		if( (pKey = f_new FlmRecord) == NULL)
		{
			rc = RC_SET( FERR_MEM);
			ViewShowRCError( "creating key", rc);
			goto Exit_False;
		}

		if (RC_BAD( rc = pKey->insertLast( 0, FLM_KEY_TAG,
										FLM_CONTEXT_TYPE, &pvFld)))
		{
			ViewShowRCError( "adding key tag", rc);
			goto Exit_False;
		}

		/* Ask for data for each field and link into key tree */

		i = 0;
		while (i < NumFields)
		{

			/* Get the name of the field and its type */

			f_sprintf( (char *)FieldName, "FIELD %u", (unsigned)pIfd->uiFldNum);
			switch( IFD_GET_FIELD_TYPE( pIfd))
			{
				case FLM_TEXT_TYPE:
					f_strcpy( (char *)FieldType, "TEXT");
					break;
				case FLM_NUMBER_TYPE:
					f_strcpy( (char *)FieldType, "NUMBER");
					break;
				case FLM_BINARY_TYPE:
					f_strcpy( (char *)FieldType, "BINARY");
					break;
				case FLM_CONTEXT_TYPE:
					f_strcpy( (char *)FieldType, "CONTEXT");
					break;
				default:
					f_sprintf( (char *)FieldType, "UNK: %u!",
						(unsigned)IFD_GET_FIELD_TYPE( pIfd));
					break;
			}
			if (pIfd->uiFlags & IFD_OPTIONAL)
				f_sprintf( (char *)Prompt, "%s (%s-OPTIONAL): ", FieldName, FieldType);
			else
				f_sprintf( (char *)Prompt, "%s (%s-REQUIRED): ", FieldName, FieldType);

			switch( IFD_GET_FIELD_TYPE( pIfd))
			{
				case FLM_TEXT_TYPE:
					if (!ViewEditText( Prompt, TempBuf, sizeof( TempBuf),
								&ValEntered))
						goto Exit_False;
					break;
				case FLM_NUMBER_TYPE:
				case FLM_CONTEXT_TYPE:
					if (!ViewGetNum( Prompt, &Num, FALSE, 4, 0xFFFFFFFF,
									&ValEntered))
						goto Exit_False;
					break;
				case FLM_BINARY_TYPE:
					Len = sizeof( TempBuf);
					if (!ViewEditBinary( Prompt, TempBuf, &Len, &ValEntered))
						goto Exit_False;
					break;
			}
			if (!ValEntered)
			{
				i++;
			}
			else
			{
				FLMUINT	uiDataType;

				/* See if the entered data can be converted to the */
				/* correct type */

				uiDataType = IFD_GET_FIELD_TYPE( pIfd);
				if (RC_BAD( rc = pKey->insertLast( 1, pIfd->uiFldNum,
													uiDataType, &pvFld)))
				{
					ViewShowRCError( "creating field", rc);
				}
				else
				{
					switch( IFD_GET_FIELD_TYPE( pIfd))
					{
						case FLM_TEXT_TYPE:
							rc = pKey->setNative( pvFld, TempBuf);
							break;
						case FLM_NUMBER_TYPE:
							rc = pKey->setUINT( pvFld, Num);
							break;
						case FLM_CONTEXT_TYPE:
							rc = pKey->setRecPointer( pvFld, Num);
							break;
						case FLM_BINARY_TYPE:
							rc = pKey->setBinary( pvFld, TempBuf, Len);
							break;
					}
					if (RC_BAD( rc))
					{
						ViewShowRCError( "putting data in field", rc);
					}
				}
				if (RC_OK(rc))
				{
					i++;
					pIfd++;
					KeyEntered = TRUE;
				}
			}
		}

		// If index is on all containers, prompt for container number.

		if (!pIxd->uiContainerNum)
		{
			f_strcpy( Prompt, "CONTAINER: ");
			if (!ViewGetNum( Prompt, &Num, FALSE, sizeof( Num), 0xFFFF,
									&ValEntered))
			{
				goto Exit_False;
			}
			if (ValEntered)
			{
				pKey->setContainerID( Num);
				KeyEntered = TRUE;
			}
		}

		/* Convert the key to binary format */

		if (!KeyEntered)
			goto Exit_False;

		if ((rc = FlmKeyBuild( gv_hViewDb, gv_uiViewSearchLfNum,
									pKey->getContainerID(), pKey, 0,
									gv_ucViewSearchKey, &gv_uiViewSearchKeyLen)) != FERR_OK)
			ViewShowRCError( "building key", rc);
		else
		{
			GetOK = TRUE;
			goto Exit_GetKey;
		}
	}

Exit_False:
	GetOK = FALSE;
Exit_GetKey:
	if (pKey)
	{
		pKey->Release();
	}
	return( GetOK);
}
Ejemplo n.º 12
0
/****************************************************************************
Desc:	Copy a database's files, including roll-forward log files.
*****************************************************************************/
FSTATIC RCODE flmCopyDb(
	FLMUINT				uiDbVersion,
	const char *		pszSrcDbName,
	const char *		pszSrcDataDir,
	const char *		pszSrcRflDir,
	const char *		pszDestDbName,
	const char *		pszDestDataDir,
	const char *		pszDestRflDir,
	STATUS_HOOK			fnStatusCallback,
	void *				UserData)
{
	RCODE						rc = FERR_OK;
	DB_COPY_INFO			DbCopyInfo;
	F_SuperFileHdl *		pSrcSFileHdl = NULL;
	F_SuperFileHdl *		pDestSFileHdl = NULL;
	F_SuperFileClient *	pSrcSFileClient = NULL;
	F_SuperFileClient *	pDestSFileClient = NULL;
	FLMUINT					uiFileNumber;
	FLMUINT					uiHighFileNumber;
	FLMUINT					uiHighLogFileNumber;
	FLMUINT64				ui64FileSize;
	FFILE *					pFile = NULL;
	FLMBOOL					bMutexLocked = FALSE;
	IF_FileHdl *			pLockFileHdl = NULL;
	IF_FileHdl *			pTmpFileHdl = NULL;
	IF_DirHdl *				pDirHdl = NULL;
	FLMBOOL					bFileLocked = FALSE;
	FLMBOOL					bWriteLocked = FALSE;
	IF_LockObject *		pWriteLockObj = NULL;
	IF_LockObject *		pFileLockObj = NULL;
	COPIED_NAME *			pCopiedList = NULL;
	FLMBOOL					bUsedFFile = FALSE;
	FLMBYTE *				pucInMemLogHdr = NULL;
	eLockType				currLockType;
	FLMUINT					uiLockThreadId;
	char *					pszActualSrcRflPath = NULL;
	char *					pszSrcPrefix = NULL;
	char *					pszActualDestRflPath = NULL;
	char *					pszDestPrefix = NULL;
	FLMBOOL					bCreatedDestRflDir = FALSE;
	F_SEM						hWaitSem = F_SEM_NULL;

	f_memset( &DbCopyInfo, 0, sizeof( DbCopyInfo));

	// Should not do anything if the source and destination names
	// are the same.

	if (f_stricmp( pszSrcDbName, pszDestDbName) == 0)
	{
		goto Exit;
	}
	
	// Allocate a semaphore

	if( RC_BAD( rc = f_semCreate( &hWaitSem)))
	{
		goto Exit;
	}
	
	// Allocate memory for paths we don't want to push onto the stack.

	if (RC_BAD( rc = f_calloc( 
		(F_PATH_MAX_SIZE + F_FILENAME_SIZE) * 2, &pszActualSrcRflPath)))
	{
		goto Exit;
	}

	pszSrcPrefix = &pszActualSrcRflPath[ F_PATH_MAX_SIZE];
	pszActualDestRflPath = &pszSrcPrefix[ F_FILENAME_SIZE];
	pszDestPrefix = &pszActualDestRflPath[ F_PATH_MAX_SIZE];

	// Set up the super file object for the source database.
	// Must at least open the control file.
	
	if( (pSrcSFileClient = f_new F_SuperFileClient) == NULL)
	{
		rc = RC_SET( FERR_MEM);
		goto Exit;
	}
	
	if( RC_BAD( rc = pSrcSFileClient->setup(
		pszSrcDbName, pszSrcDataDir, uiDbVersion)))
	{
		goto Exit;
	}
	
	if( (pSrcSFileHdl = f_new F_SuperFileHdl) == NULL)
	{
		rc = RC_SET( FERR_MEM);
		goto Exit;
	}

	if( RC_BAD( rc = pSrcSFileHdl->setup( pSrcSFileClient, 
		gv_FlmSysData.pFileHdlCache, gv_FlmSysData.uiFileOpenFlags, 0)))
	{
		goto Exit;
	}

	// Lock the destination database, if not already locked.
	// This is so we can overwrite it without necessarily
	// deleting it.  May unlock and re-lock the global mutex.

	f_mutexLock( gv_FlmSysData.hShareMutex);
	bMutexLocked = TRUE;

	if (RC_BAD( rc = flmFindFile( pszDestDbName, pszDestDataDir, &pFile)))
	{
		goto Exit;
	}

	// If we didn't find an FFILE structure, get an
	// exclusive lock on the file.

	if (!pFile)
	{
		f_mutexUnlock( gv_FlmSysData.hShareMutex);
		bMutexLocked = FALSE;

		// Attempt to get an exclusive lock on the file.

		if (RC_BAD( rc = flmCreateLckFile( pszDestDbName, &pLockFileHdl)))
		{
			goto Exit;
		}
	}
	else
	{
		// The call to flmVerifyFileUse will wait if the file is in
		// the process of being opened by another thread.

		if (RC_BAD( rc = flmVerifyFileUse( gv_FlmSysData.hShareMutex, &pFile)))
		{
			goto Exit;
		}

		// Increment the use count on the FFILE so it will not
		// disappear while we are copying the file.

		if (++pFile->uiUseCount == 1)
		{
			flmUnlinkFileFromNUList( pFile);
		}
		bUsedFFile = TRUE;

		f_mutexUnlock( gv_FlmSysData.hShareMutex);
		bMutexLocked = FALSE;
		pucInMemLogHdr = &pFile->ucLastCommittedLogHdr [0];

		// Lock the destination file object and transaction
		// object, if not already locked.
		
		pFile->pFileLockObj->getLockInfo( 0, &currLockType, &uiLockThreadId, NULL);
		if (currLockType != FLM_LOCK_EXCLUSIVE || uiLockThreadId != f_threadId())
		{
			pFileLockObj = pFile->pFileLockObj;
			pFileLockObj->AddRef();
			
			if (RC_BAD( rc = pFileLockObj->lock( hWaitSem,
				TRUE, FLM_NO_TIMEOUT, 0)))
			{
				goto Exit;
			}
			bFileLocked = TRUE;
		}

		// Lock the write object, if not already locked

		pFile->pWriteLockObj->getLockInfo( 0, &currLockType, &uiLockThreadId, NULL);
		if( currLockType != FLM_LOCK_EXCLUSIVE || 
			 uiLockThreadId != f_threadId())
		{
			pWriteLockObj = pFile->pWriteLockObj;
			pWriteLockObj->AddRef();

			// Only contention here is with the checkpoint thread - wait
			// forever until the checkpoint thread gives it up.
			
			if( RC_BAD( rc = pWriteLockObj->lock( hWaitSem, 
				TRUE, FLM_NO_TIMEOUT, 0)))
			{
				goto Exit;
			}

			bWriteLocked = TRUE;
		}
	}

	// Set up the super file object for the destination database.
	
	if( (pDestSFileClient = f_new F_SuperFileClient) == NULL)
	{
		rc = RC_SET( FERR_MEM);
		goto Exit;
	}
	
	if( RC_BAD( rc = pDestSFileClient->setup( 
		pszDestDbName, pszDestDataDir, uiDbVersion)))
	{
		goto Exit;
	}

	if( (pDestSFileHdl = f_new F_SuperFileHdl) == NULL)
	{
		rc = RC_SET( FERR_MEM);
		goto Exit;
	}
	
	if( RC_BAD( rc = pDestSFileHdl->setup( pDestSFileClient, 
		gv_FlmSysData.pFileHdlCache, gv_FlmSysData.uiFileOpenFlags,
		gv_FlmSysData.uiFileCreateFlags)))
	{
		goto Exit;
	}

	// See how many files we have and calculate the total size.

	uiHighFileNumber = 0;
	for (;;)
	{
		if( RC_BAD( rc = pSrcSFileHdl->getFileSize( 
			uiHighFileNumber, &ui64FileSize)) || !ui64FileSize)
		{
			if (rc == FERR_IO_PATH_NOT_FOUND ||
				 rc == FERR_IO_INVALID_PATH ||
				 !ui64FileSize)
			{
				// If the control file doesn't exist, we will return
				// path not found.

				if (!uiHighFileNumber)
				{
					goto Exit;
				}
				uiHighFileNumber--;
				rc = FERR_OK;
				break;
			}
			goto Exit;
		}

		DbCopyInfo.ui64BytesToCopy += ui64FileSize;
		if (uiHighFileNumber == MAX_DATA_BLOCK_FILE_NUMBER( uiDbVersion))
		{
			break;
		}
		uiHighFileNumber++;
	}

	// See how many rollback log files we have, and calculate
	// their total size.

	uiHighLogFileNumber = FIRST_LOG_BLOCK_FILE_NUMBER( uiDbVersion);
	for (;;)
	{
		if ((RC_BAD( rc = pSrcSFileHdl->getFileSize( 
			uiHighLogFileNumber, &ui64FileSize))) || !ui64FileSize)
		{
			if (rc == FERR_IO_PATH_NOT_FOUND ||
				 rc == FERR_IO_INVALID_PATH ||
				 !ui64FileSize)
			{
				if (uiHighLogFileNumber ==
							FIRST_LOG_BLOCK_FILE_NUMBER( uiDbVersion))
				{
					uiHighLogFileNumber = 0;
				}
				else
				{
					uiHighLogFileNumber--;
				}
				rc = FERR_OK;
				break;
			}
			goto Exit;
		}

		DbCopyInfo.ui64BytesToCopy += ui64FileSize;
		if (uiHighLogFileNumber == MAX_LOG_BLOCK_FILE_NUMBER( uiDbVersion))
		{
			break;
		}
		uiHighLogFileNumber++;
	}

	// Get the sizes of the roll-forward log files

	if( uiDbVersion < FLM_FILE_FORMAT_VER_4_3)
	{
		// For pre-4.3 versions, only need to copy one RFL file.

		if (RC_BAD( rc = rflGetFileName( uiDbVersion,
			pszSrcDbName, pszSrcRflDir, 1, pszActualSrcRflPath)))
		{
			goto Exit;
		}

		if( RC_BAD( rc = gv_FlmSysData.pFileSystem->openFile( 
				pszActualSrcRflPath, gv_FlmSysData.uiFileOpenFlags,
				&pTmpFileHdl)))
		{
			if (rc == FERR_IO_PATH_NOT_FOUND ||
				 rc == FERR_IO_INVALID_PATH)
			{
				rc = FERR_OK;
			}
			else
			{
				goto Exit;
			}
		}
		else
		{
			if (RC_BAD( rc = pTmpFileHdl->size( &ui64FileSize)))
			{
				goto Exit;
			}

			DbCopyInfo.ui64BytesToCopy += ui64FileSize;
			
			pTmpFileHdl->Release();
			pTmpFileHdl = NULL;
		}
	}
	else
	{
		if( RC_BAD( rc = rflGetDirAndPrefix( uiDbVersion, pszSrcDbName, 
			pszSrcRflDir, pszActualSrcRflPath, pszSrcPrefix)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = gv_FlmSysData.pFileSystem->openDir(
									pszActualSrcRflPath, (char *)"*", &pDirHdl)))
		{
			goto Exit;
		}

		for (;;)
		{
			if( RC_BAD( rc = pDirHdl->next()))
			{
				if (rc == FERR_IO_NO_MORE_FILES)
				{
					rc = FERR_OK;
					break;
				}
				else
				{
					goto Exit;
				}
			}

			// If the current file is an RFL file, increment ui64BytesToCopy

			if( rflGetFileNum( uiDbVersion, pszSrcPrefix,
				pDirHdl->currentItemName(), &uiFileNumber))
			{
				DbCopyInfo.ui64BytesToCopy += pDirHdl->currentItemSize();
			}
		}

		pDirHdl->Release();
		pDirHdl = NULL;
	}

	// Close all file handles in the source and destination

	pSrcSFileHdl->releaseFiles();
	pDestSFileHdl->releaseFiles();

	// Copy the database files.

	for (uiFileNumber = 0; uiFileNumber <= uiHighFileNumber; uiFileNumber++)
	{

		// Get the source file path and destination file path.

		if( RC_BAD( rc = pSrcSFileHdl->getFilePath( 
			uiFileNumber, DbCopyInfo.szSrcFileName)))
		{
			goto Exit;
		}
		if( RC_BAD( rc = pDestSFileHdl->getFilePath( 
			uiFileNumber, DbCopyInfo.szDestFileName)))
		{
			goto Exit;
		}

		// For the control file, don't copy first 2K - it will be set up 
		// to show maintenance in progress.  Then the first 2K will be copied
		// later.

		if (!uiFileNumber)
		{
			DbCopyInfo.bNewSrcFile = TRUE;
			if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
										2048, 0xFFFFFFFF,
										&DbCopyInfo, &pCopiedList, pucInMemLogHdr, TRUE,
										fnStatusCallback, UserData)))
			{
				goto Exit;
			}

		}
		else
		{
			DbCopyInfo.bNewSrcFile = TRUE;
			if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
										0, 0xFFFFFFFF,
										&DbCopyInfo, &pCopiedList, NULL, TRUE,
										fnStatusCallback, UserData)))
			{
				goto Exit;
			}
		}
	}

	// Copy the additional rollback log files, if any.

	for (uiFileNumber = FIRST_LOG_BLOCK_FILE_NUMBER( uiDbVersion);
		  uiFileNumber <= uiHighLogFileNumber; uiFileNumber++)
	{

		// Get the source file path and destination file path.

		if (RC_BAD( rc = pSrcSFileHdl->getFilePath( uiFileNumber,
									DbCopyInfo.szSrcFileName)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = pDestSFileHdl->getFilePath( uiFileNumber,	
			DbCopyInfo.szDestFileName)))
		{
			goto Exit;
		}

		DbCopyInfo.bNewSrcFile = TRUE;
		if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
									0, 0xFFFFFFFF,
									&DbCopyInfo, &pCopiedList, NULL, TRUE,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
	}

	// Copy the RFL files

	if( uiDbVersion < FLM_FILE_FORMAT_VER_4_3)
	{
		// Get the source file path and the destination file path.

		if (RC_BAD( rc = rflGetFileName( uiDbVersion, pszSrcDbName,
										pszSrcRflDir, 1,
										DbCopyInfo.szSrcFileName)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = rflGetFileName( uiDbVersion, pszDestDbName, 
									pszDestRflDir, 1,
									DbCopyInfo.szDestFileName)))
		{
			goto Exit;
		}

		DbCopyInfo.bNewSrcFile = TRUE;
		if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
									0, 0xFFFFFFFF,
									&DbCopyInfo, &pCopiedList, NULL, TRUE,
									fnStatusCallback, UserData)))
		{
			goto Exit;
		}
	}
	else
	{
		// Create the destination RFL directory, if needed.  The purpose of this
		// code is two-fold: 1) We want to keep track of the fact that we tried
		// to create the destination RFL directory so we can try to remove it
		// if the copy fails; 2) If the destination RFL directory path specifies
		// a directory with existing files, we want to remove them.

		if( RC_BAD( rc = rflGetDirAndPrefix( uiDbVersion, pszDestDbName, 
			pszDestRflDir, pszActualDestRflPath, pszDestPrefix)))
		{
			goto Exit;
		}

		if( RC_OK( gv_FlmSysData.pFileSystem->doesFileExist( 
			pszActualDestRflPath)))
		{
			if( gv_FlmSysData.pFileSystem->isDir( pszActualDestRflPath))
			{
				// Remove the existing directory and all files, etc.

				(void)gv_FlmSysData.pFileSystem->removeDir( 
					pszActualDestRflPath, TRUE);
			}
			else
			{
				(void)gv_FlmSysData.pFileSystem->deleteFile( pszActualDestRflPath);
			}
		}

		// Try to create the destination RFL directory.  This might fail if
		// another process was accessing the directory for some reason 
		// (i.e., from a command prompt), when we tried to remove it above.
		// We really don't care if the call to CreateDir is sucessful, because
		// when we try to create the destination files (below), the FLAIM file
		// file system code will try to create any necessary directories.

		(void)gv_FlmSysData.pFileSystem->createDir( pszActualDestRflPath);
		bCreatedDestRflDir = TRUE;

		// Copy the RFL files.  NOTE:  We need to copy all of the RFL files
		// in the source RFL directory so that they will be available
		// when performing a database restore operation.

		if (RC_BAD( rc = gv_FlmSysData.pFileSystem->openDir(
									pszActualSrcRflPath, (char *)"*", &pDirHdl)))
		{
			goto Exit;
		}

		for (;;)
		{
			if( RC_BAD( rc = pDirHdl->next()))
			{
				if (rc == FERR_IO_NO_MORE_FILES)
				{
					rc = FERR_OK;
					break;
				}
				else
				{
					goto Exit;
				}
			}

			// If the current file is an RFL file, copy it to the destination

			if( rflGetFileNum( uiDbVersion, pszSrcPrefix,
				pDirHdl->currentItemName(), &uiFileNumber))
			{
				// Get the source file path and the destination file path.

				if (RC_BAD( rc = rflGetFileName( uiDbVersion, pszSrcDbName,
												pszSrcRflDir, uiFileNumber,
												DbCopyInfo.szSrcFileName)))
				{
					goto Exit;
				}

				if (RC_BAD( rc = rflGetFileName( uiDbVersion, pszDestDbName, 
											pszDestRflDir, uiFileNumber,
											DbCopyInfo.szDestFileName)))
				{
					goto Exit;
				}

				DbCopyInfo.bNewSrcFile = TRUE;
				if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
											0, 0xFFFFFFFF,
											&DbCopyInfo, &pCopiedList, NULL, TRUE,
											fnStatusCallback, UserData)))
				{
					goto Exit;
				}
			}
		}

		pDirHdl->Release();
		pDirHdl = NULL;
	}

	// Do one final copy on the control file to copy just the first 2K

	if (RC_BAD( rc = pSrcSFileHdl->getFilePath( 0, DbCopyInfo.szSrcFileName)))
	{
		goto Exit;
	}

	if (RC_BAD( rc = pDestSFileHdl->getFilePath( 0, DbCopyInfo.szDestFileName)))
	{
		goto Exit;
	}

	DbCopyInfo.bNewSrcFile = FALSE;
	if (RC_BAD( rc = flmCopyFile( gv_FlmSysData.pFileSystem,
								0, 2048,
								&DbCopyInfo, NULL, pucInMemLogHdr, FALSE,
								fnStatusCallback, UserData)))
	{
		goto Exit;
	}

Exit:

	if (bUsedFFile)
	{
		if (!bMutexLocked)
		{
			f_mutexLock( gv_FlmSysData.hShareMutex);
			bMutexLocked = TRUE;
		}

		if (!(--pFile->uiUseCount))
		{
			flmLinkFileToNUList( pFile);
		}
	}

	if (bMutexLocked)
	{
		f_mutexUnlock( gv_FlmSysData.hShareMutex);
		bMutexLocked = FALSE;
	}

	if (bWriteLocked)
	{
		if( RC_BAD( rc = pWriteLockObj->unlock()))
		{
			goto Exit;
		}
		
		bWriteLocked = FALSE;
	}

	if (bFileLocked)
	{
		RCODE	rc3;

		if (RC_BAD( rc3 = pFileLockObj->unlock()))
		{
			if (RC_OK( rc))
				rc = rc3;
		}
		
		bFileLocked = FALSE;
	}

	if (pWriteLockObj)
	{
		pWriteLockObj->Release();
		pWriteLockObj = NULL;
	}

	if (pFileLockObj)
	{
		pFileLockObj->Release();
		pFileLockObj = NULL;
	}

	if (pLockFileHdl)
	{
		pLockFileHdl->Release();
		pLockFileHdl = NULL;
	}

	if( pTmpFileHdl)
	{
		pTmpFileHdl->Release();
	}

	if( pDirHdl)
	{
		pDirHdl->Release();
	}

	// Free all the names of files that were copied.
	// If the copy didn't finish, try to delete any files
	// that were copied.

	while (pCopiedList)
	{
		COPIED_NAME *	pNext = pCopiedList->pNext;

		// If the overall copy failed, delete the copied file.

		if (RC_BAD( rc))
		{
			(void)gv_FlmSysData.pFileSystem->deleteFile( pCopiedList->szPath);
		}

		f_free( &pCopiedList);
		pCopiedList = pNext;
	}

	if( RC_BAD( rc) && bCreatedDestRflDir)
	{
		(void)gv_FlmSysData.pFileSystem->removeDir( pszActualDestRflPath);
	}

	if( pszActualSrcRflPath)
	{
		f_free( &pszActualSrcRflPath);
	}
	
	if( hWaitSem != F_SEM_NULL)
	{
		f_semDestroy( &hWaitSem);
	}
	
	if( pSrcSFileHdl)
	{
		pSrcSFileHdl->Release();
	}
	
	if( pSrcSFileClient)
	{
		pSrcSFileClient->Release();
	}
	
	if( pDestSFileHdl)
	{
		pDestSFileHdl->Release();
	}
	
	if( pDestSFileClient)
	{
		pDestSFileClient->Release();
	}

	return( rc);
}
Ejemplo n.º 13
0
/********************************************************************
Desc:	Get command line parameters.
*********************************************************************/
FLMBOOL gigaGetParams(
	FLMINT			iArgC,
	const char **	ppszArgV)
{
	FLMBOOL			bOk = FALSE;
	FLMUINT			uiLoop;
	const char *	pszPtr;
	FLMBOOL			bHaveNumToLoad = FALSE;
#ifdef FLM_NLM
	FLMBOOL			bWaitToSync = FALSE;
#endif
	char				szMsg [100];

	gv_uiCacheSize = 0;
	gv_uiBlockCachePercentage = 50;
	gv_uiMaxDirtyCache = 0;
	gv_uiLowDirtyCache = 0;
	gv_uiTotalToLoad = 100000;
	gv_uiTransSize = 100;
	gv_uiTotalLoaded = 0;
#ifdef FLM_NLM
	f_strcpy( gv_szDibName, "sys:\\_netware\\gigatest.db");
#else
	f_strcpy( gv_szDibName, "gigatest.db");
#endif
	gv_szDataDir[ 0] = 0;
	gv_szRflDir[ 0] = 0;

	// If no parameters were entered, show a help screen.

	if( iArgC < 2)
	{
		gigaShowHelp();
		goto Exit;
	}

	uiLoop = 1;
	while( uiLoop < (FLMUINT)iArgC)
	{
		pszPtr = ppszArgV [uiLoop];

		// See if they specified an option

#ifdef FLM_UNIX
		if( *pszPtr == '-')
#else
		if( (*pszPtr == '-') || (*pszPtr == '/'))
#endif
		{
			pszPtr++;
			if ((*pszPtr == 'c') || (*pszPtr == 'C'))
			{
				gv_uiCacheSize = f_atol( (pszPtr + 1));
			}
			else if ((*pszPtr == 'i') || (*pszPtr == 'I'))
			{
				gv_uiCPInterval = f_atol( (pszPtr + 1));
			}
			else if ((*pszPtr == 'p') || (*pszPtr == 'P'))
			{
				gv_uiBlockCachePercentage = f_atol( (pszPtr + 1));
			}
			else if ((*pszPtr == 'm') || (*pszPtr == 'M'))
			{
				pszPtr++;
				if ((*pszPtr == 'd') || (*pszPtr == 'D'))
				{
					gv_uiMaxDirtyCache = f_atol( (pszPtr + 1));
				}
			}
			else if ((*pszPtr == 'l') || (*pszPtr == 'L'))
			{
				pszPtr++;
				if ((*pszPtr == 'd') || (*pszPtr == 'D'))
				{
					gv_uiLowDirtyCache = f_atol( (pszPtr + 1));
				}
			}
			else if ((*pszPtr == 't') || (*pszPtr == 'T'))
			{
				gv_uiTransSize = f_atol( (pszPtr + 1));
			}
			else if ((*pszPtr == 'n') || (*pszPtr == 'N'))
			{
				f_strcpy( gv_szDibName, pszPtr + 1);
			}
			else if (*pszPtr == 'd' || *pszPtr == 'D')
			{
				if( f_stricmp( pszPtr, "dio") == 0)
				{
					gv_bDisableDirectIO = TRUE;
				}
				else
				{
					pszPtr++;
					if (*pszPtr == 'r' || *pszPtr == 'R')
					{
						f_strcpy( gv_szRflDir, pszPtr + 1);
					}
					else if (*pszPtr == 'd' || *pszPtr == 'D')
					{
						f_strcpy( gv_szDataDir, pszPtr + 1);
					}
					else
					{
						f_sprintf( szMsg, "Invalid option %s", (pszPtr - 1));
						gigaOutputErrMsg( szMsg);
						goto Exit;
					}
				}
			}
			else if (f_stricmp( pszPtr, "B") == 0)
			{
				gv_bBatchMode = TRUE;
			}
#ifdef FLM_NLM
			else if (f_stricmp( pszPtr, "W") == 0)
			{
				bWaitToSync = TRUE;
			}
#endif
			else if (f_stricmp( pszPtr, "?") == 0 ||
						f_stricmp( pszPtr, "HELP") == 0)
			{
				gigaShowHelp();
				goto Exit;
			}
			else
			{
				f_sprintf( szMsg, "Invalid option %s", pszPtr);
				gigaOutputErrMsg( szMsg);
				goto Exit;
			}
		}
		else if (f_stricmp( pszPtr, "?") == 0)
		{
			gigaShowHelp();
			return( FALSE);
		}
		else if (!bHaveNumToLoad)
		{
			gv_uiTotalToLoad = f_atol( pszPtr);
			bHaveNumToLoad = TRUE;
		}
		uiLoop++;
	}

#ifdef FLM_NLM
	if (!bWaitToSync && !gv_bSynchronized)
	{
		SynchronizeStart();
		gv_bSynchronized = TRUE;
	}
#endif

	bOk = TRUE;
Exit:
	return( bOk);
}
Ejemplo n.º 14
0
/********************************************************************
Desc: ?
*********************************************************************/
FSTATIC FLMBOOL bldParseHdrInfo(
	const char *	pucBuffer)
{
	FLMUINT			uiNum;
	FLMBOOL			bHaveParam;
	CREATE_OPTS		CreateOpts;
	FLMUINT			uiFieldNum;

	f_memcpy( &CreateOpts, &gv_DefaultCreateOpts, sizeof( CREATE_OPTS));
	uiFieldNum = 1;
	for (;;)
	{
		uiNum = 0;
		bHaveParam = FALSE;
		while ((*pucBuffer == ' ') ||
				 (*pucBuffer == ':') ||
				 (*pucBuffer == ',') ||
				 (*pucBuffer == ';') ||
				 (*pucBuffer == '\t'))
		{
			pucBuffer++;
		}

		if( uiFieldNum == 8)	// Language
		{
			char		pszTmpBuf[ 100];
			FLMUINT	uiTmpLen = 0;

			while ((*pucBuffer) &&
					 (*pucBuffer != ':') &&
					 (*pucBuffer != ',') &&
					 (*pucBuffer != ';') &&
					 (*pucBuffer != ' ') &&
					 (*pucBuffer != '\t'))
			{
				pszTmpBuf[ uiTmpLen++] = *pucBuffer++;
			}

			pszTmpBuf[ uiTmpLen] = 0;
			if( uiTmpLen)
			{
				uiNum = f_languageToNum( pszTmpBuf);
				if( (!uiNum) && (f_stricmp( pszTmpBuf, "US") != 0))
				{
					bldShowError( "Illegal language in header information");
					return( FALSE);
				}
				bHaveParam = TRUE;
			}
		}
		else
		{
			while( (*pucBuffer >= '0') && (*pucBuffer <= '9'))
			{
				uiNum *= 10;
				uiNum += (FLMUINT)(*pucBuffer - '0');
				pucBuffer++;
				bHaveParam = TRUE;
			}
		}

		if( ((*pucBuffer != 0) &&
			  (*pucBuffer != ' ') &&
			  (*pucBuffer != ':') &&
			  (*pucBuffer != ',') &&
			  (*pucBuffer != ';') &&
			  (*pucBuffer != '\t')))
		{
			bldShowError( "Illegal value in header information");
			return( FALSE);
		}

		if( bHaveParam)
		{
			switch( uiFieldNum)
			{
				case 1:
					if( uiNum != 0 && !VALID_BLOCK_SIZE( uiNum))
					{
						bldShowError( "Illegal block size");
						return( FALSE);
					}
					CreateOpts.uiBlockSize = uiNum;
					break;
				case 4:
					if( uiNum > 255)
					{
						bldShowError( "Illegal application major version");
						return( FALSE);
					}
					CreateOpts.uiAppMajorVer = uiNum;
					break;
				case 5:
					if( uiNum > 255)
					{
						bldShowError( "Illegal application minor version");
						return( FALSE);
					}
					CreateOpts.uiAppMinorVer = uiNum;
					break;
				case 6:
					CreateOpts.uiMaxRflFileSize = uiNum;
					break;
				case 7:
					CreateOpts.uiDefaultLanguage = uiNum;
					break;
				case 8:
					CreateOpts.uiVersionNum = uiNum;
					break;
				default:
					bldShowError( "Too many parameters in header information");
					return( FALSE);
			}
		}

		if( !(*pucBuffer))
		{
			break;
		}

		uiFieldNum++;
	}

	gv_bFixHdrInfo = TRUE;
	f_memcpy( &gv_DefaultCreateOpts, &CreateOpts, sizeof( CREATE_OPTS));
	return( TRUE);
}
Ejemplo n.º 15
0
/********************************************************************
Desc: ?
*********************************************************************/
FSTATIC FLMBOOL bldGetParams(
	FLMINT			iArgC,
	const char **	ppszArgV)
{
#define MAX_ARGS     30
	FLMUINT			uiLoop;
	char				szErrMsg [100];
	const char *	pszPtr;
	const char *	ppszArgs[ MAX_ARGS];
	char				szCommandBuffer [300];

	gv_szSrcFileName [0] = 0;
	gv_szSrcDataDir [0] = 0;
	gv_szDestFileName [0] = 0;
	gv_szDestDataDir [0] = 0;
	gv_szDestRflDir [0] = 0;
	gv_szDictFileName [0] = 0;
	gv_szLogFileName [0] = 0;
	gv_bFixHdrInfo = FALSE;
	gv_DefaultCreateOpts.uiBlockSize = DEFAULT_BLKSIZ;
	gv_DefaultCreateOpts.uiMinRflFileSize = DEFAULT_MIN_RFL_FILE_SIZE;
	gv_DefaultCreateOpts.uiMaxRflFileSize = DEFAULT_MAX_RFL_FILE_SIZE;
	gv_DefaultCreateOpts.bKeepRflFiles = DEFAULT_KEEP_RFL_FILES_FLAG;
	gv_DefaultCreateOpts.bLogAbortedTransToRfl = DEFAULT_LOG_ABORTED_TRANS_FLAG;
	gv_DefaultCreateOpts.uiDefaultLanguage = DEFAULT_LANG;
	gv_DefaultCreateOpts.uiVersionNum = FLM_CUR_FILE_FORMAT_VER_NUM;
	gv_DefaultCreateOpts.uiAppMajorVer = 
	gv_DefaultCreateOpts.uiAppMinorVer = 0;
	gv_uiCacheSize = 30000;
	gv_bBatchMode = FALSE;

	// Ask the user to enter parameters if none were entered on the command
	// line.

	if( iArgC < 2)
	{
		for (;;)
		{
			f_conStrOut( "\nRebuild Params (enter ? for help): ");
			szCommandBuffer[ 0] = 0;
			f_conLineEdit( szCommandBuffer, sizeof( szCommandBuffer) - 1);
			if( gv_bShutdown)
			{
				return( FALSE);
			}

			if( f_stricmp( szCommandBuffer, "?") == 0)
			{
				bldShowHelp();
			}
			else
			{
				break;
			}
		}
		flmUtilParseParams( szCommandBuffer, MAX_ARGS, &iArgC, &ppszArgs [1]);
		ppszArgs[ 0] = ppszArgV[ 0];
		iArgC++;
		ppszArgV = &ppszArgs[ 0];
	}

	uiLoop = 1;
	while (uiLoop < (FLMUINT)iArgC)
	{
		pszPtr = ppszArgV [uiLoop];

		// See if they specified an option

#ifdef FLM_UNIX
		if (*pszPtr == '-')
#else
		if (*pszPtr == '-' || *pszPtr == '/')
#endif
		{
			pszPtr++;
			if (*pszPtr == 'c' || *pszPtr == 'C')
			{
				gv_uiCacheSize = f_atoi( (pszPtr + 1));
			}
			else if (*pszPtr == 'd' || *pszPtr == 'D')
			{
				pszPtr++;
				if (*pszPtr == 'r' || *pszPtr == 'R')
				{
					pszPtr++;
					if (*pszPtr)
					{
						f_strcpy( gv_szDestRflDir, pszPtr);
					}
					else
					{
						bldShowError(
							"Destination RFL directory not specified");
						return( FALSE);
					}
				}
				else if (*pszPtr == 'd' || *pszPtr == 'D')
				{
					pszPtr++;
					if (*pszPtr)
					{
						f_strcpy( gv_szDestDataDir, pszPtr);
					}
					else
					{
						bldShowError(
							"Destination data directory not specified");
						return( FALSE);
					}
				}
				else if (*pszPtr == 'c' || *pszPtr == 'C')
				{
					pszPtr++;
					if (*pszPtr)
					{
						f_strcpy( gv_szDictFileName, pszPtr);
					}
					else
					{
						bldShowError(
							"Dictionary file name not specified");
						return( FALSE);
					}
				}
				else
				{
					f_sprintf( szErrMsg, "Invalid option %s", pszPtr-1);
					bldShowError( szErrMsg);
					return( FALSE);
				}
			}
			else if (*pszPtr == 's' || *pszPtr == 'S')
			{
				pszPtr++;
				if (*pszPtr == 'd' || *pszPtr == 'D')
				{
					pszPtr++;
					if (*pszPtr)
					{
						f_strcpy( gv_szSrcDataDir, pszPtr);
					}
					else
					{
						bldShowError(
							"Source data directory not specified");
						return( FALSE);
					}
				}
				else
				{
					f_sprintf( szErrMsg, "Invalid option %s", pszPtr-1);
					bldShowError( szErrMsg);
					return( FALSE);
				}
			}
			else if (*pszPtr == 'h' || *pszPtr == 'H')
			{
				pszPtr++;
				if( *pszPtr)
				{
					if( !bldParseHdrInfo( pszPtr))
					{
						return( FALSE);
					}
				}
				else
				{
					bldShowError( "Block sizes not specified");
					return( FALSE);
				}
			}
			else if (*pszPtr == 'l' || *pszPtr == 'L')
			{
				pszPtr++;
				if (*pszPtr)
				{
					f_strcpy( gv_szLogFileName, pszPtr);
				}
				else
				{
					bldShowError( "Log file name not specified");
					return( FALSE);
				}
			}
			else if (f_stricmp( pszPtr, "P") == 0)
			{
				gv_bPauseBeforeExiting = TRUE;
			}
			else if (f_stricmp( pszPtr, "B") == 0)
			{
				gv_bBatchMode = TRUE;
			}
			else if (f_stricmp( pszPtr, "?") == 0)
			{
				goto Show_Help;
			}
			else
			{
				f_sprintf( szErrMsg, "Invalid option %s", pszPtr);
				bldShowError( szErrMsg);
				return( FALSE);
			}
		}
		else if (f_stricmp( pszPtr, "?") == 0)
		{
Show_Help:
			bldShowHelp();
			gv_bPauseBeforeExiting = TRUE;
			return( FALSE);
		}
		else if (!gv_szSrcFileName[ 0])
		{
			f_strcpy( gv_szSrcFileName, pszPtr);
		}
		else if (!gv_szDestFileName[ 0])
		{
			f_strcpy( gv_szDestFileName, pszPtr);
		}
		uiLoop++;
	}

	if (!gv_szSrcFileName [0] || !gv_szDestFileName [0])
	{
		goto Show_Help;
	}
	
	return( TRUE);
}