Пример #1
0
/****************************************************************************
Desc:
****************************************************************************/
FlagSet::FlagSet( 
	const FlagSet&		fs)
{
	if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * fs.m_uiNumElems,
										&m_ppucElemArray)))
	{
		flmAssert( 0);
	}
	
	if( RC_BAD( f_alloc( sizeof( FLMBOOL) * fs.m_uiNumElems,
										&m_pbFlagArray)))
	{
		flmAssert( 0);
	}
	
	f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * fs.m_uiNumElems);
	
	for( FLMUINT uiLoop = 0; uiLoop < fs.m_uiNumElems; uiLoop++)
	{
		if( RC_BAD( f_alloc( f_strlen( (char *)fs.m_ppucElemArray[uiLoop]) + 1,
				&m_ppucElemArray[ uiLoop])))
		{
			flmAssert( 0);
		}
		
		f_strcpy( (char *)m_ppucElemArray[uiLoop], 
					 (char *)fs.m_ppucElemArray[uiLoop]);
	}
	
	m_uiNumElems = fs.m_uiNumElems;
}
Пример #2
0
/****************************************************************************
Desc:
****************************************************************************/
void FlagSet::init( 
	FLMBYTE **		ppucElemArray,
	FLMUINT			uiNumElems)
{
	reset();
	
	if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiNumElems,
										&m_ppucElemArray)))
	{
		flmAssert( 0);
	}
	
	if( RC_BAD( f_alloc( sizeof( FLMBOOL) * uiNumElems,
										&m_pbFlagArray)))
	{
		flmAssert( 0);
	}
	
	f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * uiNumElems);
	
	for( FLMUINT uiLoop = 0; uiLoop < uiNumElems; uiLoop++)
	{
		if( RC_BAD( f_alloc( f_strlen( (char *)ppucElemArray[ uiLoop]) + 1,
				&m_ppucElemArray[ uiLoop])))
		{
			flmAssert( 0);
		}
		
		f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)ppucElemArray[uiLoop]);
	}
	
	m_uiNumElems = uiNumElems;
}
Пример #3
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::resize( void)
{
	RCODE			rc = FERR_OK;
	FLMUINT		uiLoop;
	char **		ppszTemp = NULL;

	if( RC_BAD( rc = f_alloc( m_uiCapacity * GROW_FACTOR * sizeof(char*), 
		&ppszTemp)))
	{
		goto Exit;
	}

	m_uiCapacity *= GROW_FACTOR;
	
	for( uiLoop = 0; uiLoop < m_uiNumEntries; uiLoop++)
	{
		if( RC_BAD( rc = f_alloc( f_strlen( m_ppszArgs[ uiLoop]) + 1, 
			&ppszTemp[ uiLoop])))
		{
			f_free( &ppszTemp);
			goto Exit;
		}
		
		f_strcpy( ppszTemp[uiLoop], m_ppszArgs[uiLoop]);
	}

	f_free( &m_ppszArgs);
	m_ppszArgs = ppszTemp;

Exit:

	return( rc);
}
Пример #4
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE	SortKeyTestImpl::createNameDoc( 
	char *		pszNames[ 2])
{
	RCODE						rc = NE_XFLM_OK;
	ELEMENT_NODE_INFO 	pNameNodes[2];

	f_memset( pNameNodes, 0, sizeof( pNameNodes));

	if ( RC_BAD( rc = f_alloc( 
		f_strlen( pszNames[0]) + 1, &pNameNodes[0].pvData)))
	{
		MAKE_FLM_ERROR_STRING( "f_alloc failed.", m_szDetails, rc);
		goto Exit;
	}

	f_strcpy( (char*)pNameNodes[0].pvData, pszNames[0]);
	pNameNodes[0].uiDataType = XFLM_TEXT_TYPE;
	pNameNodes[0].uiDataSize = f_strlen( pszNames[0]);
	pNameNodes[0].uiDictNum = FIRST_NAME_ID;

	if ( RC_BAD( rc = f_alloc( 
		f_strlen( pszNames[1]) + 1, &pNameNodes[1].pvData)))
	{
		MAKE_FLM_ERROR_STRING( "f_alloc failed.", m_szDetails, rc);
		goto Exit;
	}

	f_strcpy( (char*)pNameNodes[1].pvData, pszNames[1]);
	pNameNodes[1].uiDataType = XFLM_TEXT_TYPE;
	pNameNodes[1].uiDataSize = f_strlen( pszNames[0]);
	pNameNodes[1].uiDictNum = LAST_NAME_ID;

	if ( RC_BAD( rc = createCompoundDoc( pNameNodes, 2, NULL)))
	{
		goto Exit;
	}

Exit:

	if ( pNameNodes[0].pvData)
	{
		f_free( &pNameNodes[0].pvData);
	}

	if ( pNameNodes[1].pvData)
	{
		f_free( &pNameNodes[1].pvData);
	}

	return rc;
}
Пример #5
0
/****************************************************************************
Desc:
****************************************************************************/
FlagSet FlagSet::crossProduct( 
	FlagSet&		fs2)
{
	FlagSet		fsCross;
	FLMUINT		uiLoop1;
	FLMUINT		uiCrossProductElems = this->getNumElements() * fs2.getNumElements();
	FLMBYTE **	ppszCross = NULL;
	
	if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiCrossProductElems,
		&ppszCross)))
	{
		flmAssert( 0);
		goto Exit;
	}

	for( uiLoop1 = 0; uiLoop1 < this->getNumElements(); uiLoop1++)
	{
		for( FLMUINT uiLoop2 = 0; uiLoop2 < fs2.getNumElements(); uiLoop2++)
		{
			FLMUINT	uiIndex = uiLoop1 * fs2.getNumElements() + uiLoop2;
			
			if( RC_BAD( f_alloc( f_strlen((char *)this->m_ppucElemArray[ uiLoop1]) + 
						f_strlen((char *)fs2.m_ppucElemArray[ uiLoop2]) + 1,
					&ppszCross[ uiIndex])))
			{
				flmAssert( 0);
			}
			
			f_strcpy( (char *)ppszCross[ uiIndex], 
				(char *)this->m_ppucElemArray[ uiLoop1]);
				
			f_strcat( (char *)ppszCross[ uiIndex], 
				(char *)fs2.m_ppucElemArray[ uiLoop2]);
		}
	}
	
	fsCross.init( ppszCross, uiCrossProductElems);

	for( uiLoop1 = 0; uiLoop1 < uiCrossProductElems; uiLoop1++)
	{
		f_free( &ppszCross[ uiLoop1]);
	}
	
	f_free( &ppszCross);
	
Exit:

	return( fsCross);
}
Пример #6
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::addArg( 
	const char *	pszArg)
{
	RCODE		rc = FERR_OK;

	if( m_uiNumEntries >= m_uiCapacity)
	{
		if( RC_BAD( rc = resize()))
		{
			goto Exit;
		}
	}

	if( RC_BAD( rc = f_alloc( f_strlen( pszArg) + 1,
		&m_ppszArgs[ m_uiNumEntries])))
	{
		goto Exit;
	}

	f_strcpy( m_ppszArgs[ m_uiNumEntries++], pszArg);

Exit:

	return( rc);
}
Пример #7
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE IFlmTestLogger::appendString( 
	const char *		pszString)
{
	RCODE				rc = FERR_OK;
	char *			pszTemp = NULL;

	if ( RC_BAD( rc = f_alloc( f_strlen( pszString) + 3, &pszTemp)))
	{
		goto Exit;
	}

	f_sprintf( pszTemp, "%s\n", pszString);

	if( RC_BAD( rc = f_filecat( m_szFilename, pszString)))
	{
		goto Exit;
	}

Exit:

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

	return rc;
}
Пример #8
0
RCODE f_semCreate(
	F_SEM *		phSem)
{
	RCODE			rc = NE_FLM_OK;

	f_assert( phSem != NULL);

	if( RC_BAD( rc = f_alloc( sizeof( sema_t), phSem)))
	{
		goto Exit;
	}

#if defined( FLM_SOLARIS)
	if( sema_init( (sema_t *)*phSem, 0, USYNC_THREAD, NULL) < 0) 
#else
	if( sema_init( (sema_t *)*phSem) < 0)
#endif
	{
		f_free( phSem);
		*phSem = F_SEM_NULL;
		rc = RC_SET( NE_FLM_COULD_NOT_CREATE_SEMAPHORE);
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #9
0
/****************************************************************************
Desc:
****************************************************************************/
XFLXPC RCODE XFLAPI xflaim_DOMNode_getString(
	IF_DOMNode *	pThisNode,
	IF_Db *			pDb,
	FLMUINT32		ui32StartPos,
	FLMUINT32		ui32NumChars,
	FLMUNICODE **	ppuzValue)
{
	RCODE		rc;
	FLMUINT	uiNumChars;
	FLMUINT	uiBufSize;

	*ppuzValue = NULL;
	if (RC_BAD( rc = pThisNode->getUnicodeChars( pDb, &uiNumChars)))
	{
		goto Exit;
	}
	if ((FLMUINT)ui32StartPos >= uiNumChars)
	{
		if (RC_BAD( rc = f_alloc( sizeof( FLMUNICODE), ppuzValue)))
		{
			goto Exit;	
		}
		(*ppuzValue) [0] = 0;
		goto Exit;
	}
	uiNumChars -= (FLMUINT)ui32StartPos;
	if (ui32NumChars && (FLMUINT)ui32NumChars < uiNumChars)
	{
		uiNumChars = (FLMUINT)ui32NumChars;
	}

	uiBufSize = (uiNumChars + 1) * sizeof( FLMUNICODE);
	if (RC_BAD( rc = f_alloc( uiBufSize, ppuzValue)))
	{
		goto Exit;	
	}

	if (RC_BAD( rc = pThisNode->getUnicode( pDb, *ppuzValue, uiBufSize,
											(FLMUINT)ui32StartPos, uiNumChars, NULL)))
	{
		goto Exit;
	}
	
Exit:

	return( rc);
}
Пример #10
0
/****************************************************************************
Desc:	Make sure the vector array is allocated at least up to the element
		number that is passed in.
****************************************************************************/
RCODE F_DataVector::allocVectorArray(
	FLMUINT	uiElementNumber)
{
	RCODE	rc = NE_XFLM_OK;

	if (uiElementNumber >= m_uiNumElements)
	{

		// May need to allocate a new vector array

		if (uiElementNumber >= m_uiVectorArraySize)
		{
			FLMUINT					uiNewArraySize = uiElementNumber + 32;
			F_VECTOR_ELEMENT *	pNewVector;

			if (m_pVectorElements == &m_VectorArray [0])
			{
				if (RC_BAD( rc = f_alloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
											&pNewVector)))
				{
					goto Exit;
				}
				if (m_uiNumElements)
				{
					f_memcpy( pNewVector, m_pVectorElements,
						m_uiNumElements * sizeof( F_VECTOR_ELEMENT));
				}
			}
			else
			{
				pNewVector = m_pVectorElements;

				if (RC_BAD( rc = f_realloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
											&pNewVector)))
				{
					goto Exit;
				}

			}
			m_pVectorElements = pNewVector;
			m_uiVectorArraySize = uiNewArraySize;
		}

		// Initialized everything between the old last element and
		// the new element, including the new element, to zeroes.

		f_memset( &m_pVectorElements [m_uiNumElements], 0,
			sizeof( F_VECTOR_ELEMENT) *
			(uiElementNumber - m_uiNumElements + 1));

		m_uiNumElements = uiElementNumber + 1;
	}

Exit:

	return( rc);
}
Пример #11
0
/******************************************************************
Desc:	Implements the addChar function of the DynamicBuffer class
*******************************************************************/
RCODE F_DynamicBuffer::addChar(
	char			ucCharacter)
{
	RCODE			rc = FERR_OK;

	if (!m_bSetup)
	{
		flmAssert( 0);
		rc = RC_SET( FERR_FAILURE);
		goto Exit;

	}

	f_mutexLock( m_hMutex);

	// Is there room for just one more character plus a terminator?
	if ((m_uiBuffSize - m_uiUsedChars) > 1)
	{
		m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
		m_pucBuffer[ m_uiUsedChars] = 0;
	}
	else
	{
		// Allocate a new buffer or increase the size of the existing one.
		if( !m_uiBuffSize)
		{
			if( RC_BAD( rc = f_alloc( 50, &m_pucBuffer)))
			{
				goto Exit;
			}
			m_uiBuffSize = 50;
		}
		else
		{
			if( RC_BAD( rc = f_realloc( m_uiBuffSize + 50,  &m_pucBuffer)))
			{
				goto Exit;
			}
			m_uiBuffSize += 50;
		}


		m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
		m_pucBuffer[ m_uiUsedChars] = 0;
	}

Exit:

	if ( m_bSetup)
	{
		f_mutexUnlock( m_hMutex);
	}

	return( rc);
}
Пример #12
0
/****************************************************************************
Name:	update
Desc:
*****************************************************************************/
RCODE F_DynamicList::update(
	FLMUINT					uiKey,
	F_DLIST_DISP_HOOK 	pDisplayHook,
	void *					pvData,
	FLMUINT					uiDataLen)
{
	DLIST_NODE *	pTmp;
	RCODE				rc = NE_FLM_OK;

	if( (pTmp = getNode( uiKey)) == NULL)
	{
		rc = insert( uiKey, pDisplayHook, pvData, uiDataLen);
		goto Exit;
	}

	if( !pTmp->pvData || pTmp->uiDataLen != uiDataLen)
	{
		if( pTmp->pvData)
		{
			f_free( &pTmp->pvData);
			pTmp->uiDataLen = 0;
		}

		if( uiDataLen)
		{
			if( RC_BAD( rc = f_alloc( uiDataLen, &pTmp->pvData)))
			{
				goto Exit;
			}
		}
	}

	if( uiDataLen)
	{
		f_memcpy( pTmp->pvData, pvData, uiDataLen);
		pTmp->uiDataLen = uiDataLen;
	}

	m_bChanged = TRUE;

Exit:

	return( rc);
}
Пример #13
0
/****************************************************************************
Desc:
****************************************************************************/
void flmDbgLogInit( void)
{
	char	szLogPath[ 256];
	RCODE	rc	= NE_SFLM_OK;

	flmAssert( g_hDbgLogMutex == F_MUTEX_NULL);

	// Allocate a buffer for the log

	if (RC_BAD( rc = f_alloc( DBG_LOG_BUFFER_SIZE + 1024, &g_pszLogBuf)))
	{
		goto Exit;
	}

	// Create the mutex

	if (RC_BAD( rc = f_mutexCreate( &g_hDbgLogMutex)))
	{
		goto Exit;
	}

	// Build the file path

#ifdef FLM_NLM
	f_strcpy( szLogPath, "SYS:\\FLMDBG.LOG");
#else
	f_sprintf( szLogPath, "FLMDBG.LOG");
#endif

	// Create the file - truncate if it exists already.

	if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->Create( szLogPath, 
		XFLM_IO_RDWR | XFLM_IO_SH_DENYNONE | XFLM_IO_DIRECT, &g_pLogFile)))
	{
		goto Exit;
	}

Exit:

	flmAssert( RC_OK( rc));
}
Пример #14
0
/****************************************************************************
Desc:	Allocate data for a unicode element and retrieve it.
****************************************************************************/
RCODE XFLAPI F_DataVector::getUnicode(
	FLMUINT			uiElementNumber,
	FLMUNICODE **	ppuzUnicode)
{
	RCODE		rc = NE_XFLM_OK;
	FLMUINT	uiLen;

	// Get the unicode length (does not include NULL terminator)

	if (RC_BAD( rc = getUnicode( uiElementNumber, NULL, &uiLen)))
	{
		goto Exit;
	}

	if (uiLen)
	{

		// Account for NULL character.

		uiLen += sizeof( FLMUNICODE);

		if( RC_BAD( rc = f_alloc( uiLen, ppuzUnicode)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = getUnicode( uiElementNumber, *ppuzUnicode,
									&uiLen)))
		{
			goto Exit;
		}
	}
	else
	{
		*ppuzUnicode = NULL;
	}

Exit:

	return( rc);
}
Пример #15
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE FTKAPI F_IOBuffer::addCallbackData(
	void *							pvData)
{
	RCODE			rc = NE_FLM_OK;
	
	if( m_uiCallbackDataCount >= m_uiMaxCallbackData)
	{
		if( m_ppCallbackData == m_callbackData)
		{
			void **	pNewTable;
			
			if( RC_BAD( rc = f_alloc( 
				(m_uiCallbackDataCount + 1) * sizeof( void *), &pNewTable)))
			{
				goto Exit;
			}
			
			f_memcpy( pNewTable, m_ppCallbackData, 
				m_uiMaxCallbackData * sizeof( void *));
			m_ppCallbackData = pNewTable;
		}
		else
		{
			if( RC_BAD( rc = f_realloc( 
				(m_uiCallbackDataCount + 1) * sizeof( void *), &m_ppCallbackData)))
			{
				goto Exit;
			}
		}
		
		m_uiMaxCallbackData = m_uiCallbackDataCount + 1;
	}
	
	m_ppCallbackData[ m_uiCallbackDataCount] = pvData;
	m_uiCallbackDataCount++;
	
Exit:

	return( rc);
}
Пример #16
0
/**************************************************************************
Desc:		Get the Flaim collating string and convert back to a text string
Ret:		Length of new wpStr
Notes:	Allocates the area for the word string buffer if will be over 256.
***************************************************************************/
RCODE flmColText2StorageText(
	const FLMBYTE *	pucColStr,				// Points to the collated string
	FLMUINT				uiColStrLen,			// Length of the collated string
	FLMBYTE *			pucStorageBuf,			// Output string to build - TEXT string
	FLMUINT *			puiStorageLen,			// In: Size of buffer, Out: Bytes used
	FLMUINT	   		uiLang,
	FLMBOOL *			pbDataTruncated,		// Sets to TRUE if data had been truncated
	FLMBOOL *			pbFirstSubstring)		// Sets to TRUE if first substring
{
#define LOCAL_CHARS		150
	FLMBYTE		ucWPStr[ LOCAL_CHARS * 2 + LOCAL_CHARS / 5 ];	// Sample + 20%
	FLMBYTE *  	pucWPPtr = NULL;
	FLMBYTE *	pucAllocatedWSPtr = NULL;
	FLMUINT		uiWPStrLen;
	FLMBYTE *	pucStoragePtr;
	FLMUINT		uiUnconvChars;
	FLMUINT		uiTmp;
	FLMUINT		uiMaxStorageBytes = *puiStorageLen;
	FLMUINT		uiMaxWPBytes;
	FLMUINT		uiStorageOffset;
	FLMBYTE		ucTmpSen[ 5];
	FLMBYTE *	pucTmpSen = &ucTmpSen[ 0];
	RCODE			rc = NE_FLM_OK;

	if( uiColStrLen > LOCAL_CHARS)
	{
		// If it won't fit, allocate a new buffer

		if( RC_BAD( rc = f_alloc( SFLM_MAX_KEY_SIZE * 2, &pucWPPtr)))
		{
			goto Exit;
		}

		pucAllocatedWSPtr = pucWPPtr;
		uiMaxWPBytes = uiWPStrLen = SFLM_MAX_KEY_SIZE * 2;
	}
	else
	{
		pucWPPtr = &ucWPStr[ 0];
		uiMaxWPBytes = uiWPStrLen = sizeof( ucWPStr);
	}

 	if( (uiLang >= FLM_FIRST_DBCS_LANG) &&
 		 (uiLang <= FLM_LAST_DBCS_LANG))
 	{
		if( RC_BAD( rc = f_asiaColStr2WPStr( pucColStr, uiColStrLen,
			pucWPPtr, &uiWPStrLen, &uiUnconvChars,
			pbDataTruncated, pbFirstSubstring)))
		{
			goto Exit;
		}
	}
	else
	{
		if( RC_BAD( rc = f_colStr2WPStr( pucColStr, uiColStrLen,
			pucWPPtr, &uiWPStrLen, uiLang, &uiUnconvChars,
			pbDataTruncated, pbFirstSubstring)))
		{
			goto Exit;
		}
	}

	// Copy word string to the storage string area

	uiWPStrLen >>= 1;	// Convert # of bytes to # of words
	pucStoragePtr = pucStorageBuf;
	uiStorageOffset = 0;

	// Encode the number of characters as a SEN.  If pucEncPtr is
	// NULL, the caller is only interested in the length of the encoded
	// string, so a temporary buffer is used to call f_encodeSEN.

	uiTmp = f_encodeSEN( uiWPStrLen - uiUnconvChars, &pucTmpSen);
	if( (uiStorageOffset + uiTmp) >= uiMaxStorageBytes)
	{
		rc = RC_SET( NE_FLM_CONV_DEST_OVERFLOW);
		goto Exit;
	}
	f_memcpy( pucStoragePtr, &ucTmpSen[ 0], uiTmp);
	uiStorageOffset += uiTmp;

	// Encode each of the WP characters into UTF-8

	while( uiWPStrLen--)
	{
		FLMBYTE			ucChar;
		FLMBYTE			ucCharSet;
		FLMUNICODE		uChar;

		// Put the character in a local variable for speed

		ucChar = *pucWPPtr++;
		ucCharSet = *pucWPPtr++;

		if( ucCharSet == 0xFF && ucChar == 0xFF)
		{
			uChar = (((FLMUNICODE)*(pucWPPtr + 1)) << 8) | *pucWPPtr;
			pucWPPtr += 2;
			uiWPStrLen--; // Skip past 4 bytes for UNICODE
		}
		else
		{
			if( RC_BAD( rc = f_wpToUnicode(
				(((FLMUINT16)ucCharSet) << 8) + ucChar, &uChar)))
			{
				goto Exit;
			}
		}

		uiTmp = uiMaxStorageBytes - uiStorageOffset;
		if( RC_BAD( rc = f_uni2UTF8( uChar,
			&pucStorageBuf[ uiStorageOffset], &uiTmp)))
		{
			goto Exit;
		}
		uiStorageOffset += uiTmp;
	}

	if( uiStorageOffset >= uiMaxStorageBytes)
	{
		rc = RC_SET( NE_FLM_CONV_DEST_OVERFLOW);
		goto Exit;
	}

	// Tack on a trailing NULL byte

	pucStorageBuf[ uiStorageOffset++] = 0;

	// Return the length of the storage buffer

	*puiStorageLen = uiStorageOffset;

Exit:

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

	return( rc);
}
Пример #17
0
/****************************************************************************
Desc:	Prints the web page for the SCacheHashTable
****************************************************************************/
RCODE F_SCacheHashTablePage::display(
	FLMUINT			uiNumParams,
	const char ** 	ppszParams)
{
	RCODE			rc = FERR_OK;
	FLMBOOL		bRefresh;
	FLMBOOL		bHighlight = TRUE;
  	FLMUINT		uiLoop;
	FLMUINT		uiHashTableSize;
	FLMUINT		uiUsedEntries = 0;
	char			szStart[10];
	char			szRefresh[] = "&Refresh";
	FLMUINT		uiStart;
	FLMUINT		uiNewStart;
	char *		pszTemp;
#define NUM_ENTRIES 20
	char *		pszHTLinks[NUM_ENTRIES];

	F_UNREFERENCED_PARM( uiNumParams);
	F_UNREFERENCED_PARM( ppszParams);

	// Check for the refresh parameter
	
	bRefresh = DetectParameter( uiNumParams, ppszParams, "Refresh");
	if (!bRefresh)
	{
		szRefresh[0]='\0';  // Effectively turns szRefresh into a null string
	}

	// Get the starting entry number...
	if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
												  "Start", sizeof( szStart),
												  szStart)))
	{  
		flmAssert( 0);  
		goto Exit;
	}
	uiStart = f_atoud( szStart);

	// Allocate space for the hyperlink text
	for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
	{
		if( RC_BAD( rc = f_alloc( 250, &pszHTLinks[ uiLoop])))
		{
			printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
			goto Exit;
		}

		pszHTLinks[uiLoop][0] = '\0';
	}

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

	// Lock the database
	f_mutexLock( gv_FlmSysData.hShareMutex);

	// Get the number of entries in the hash table
	uiHashTableSize = gv_FlmSysData.SCacheMgr.uiHashTblSize;
	
	// May need to modify starting number if it's out of range...
	if ((uiStart + NUM_ENTRIES) >= uiHashTableSize)
	{
		uiStart = uiHashTableSize - NUM_ENTRIES;
	}


	// Loop through the entire table counting the number of entries in use
	// If the entry is one of the one's we're going to display, store the 
	// appropriate text in pszHTLinks
	for (uiLoop = 0; uiLoop < uiHashTableSize; uiLoop++)
	{
		if (gv_FlmSysData.SCacheMgr.ppHashTbl[uiLoop])
		{
			uiUsedEntries++;
		}

		if (	(uiLoop >= uiStart) &&
				(uiLoop < (uiStart + NUM_ENTRIES)) )
		{
			// This is one of the entries that we will display
			if (gv_FlmSysData.SCacheMgr.ppHashTbl[uiLoop])
			{
				flmBuildSCacheBlockString( pszHTLinks[uiLoop - uiStart], 
					gv_FlmSysData.SCacheMgr.ppHashTbl[uiLoop]);
			}

		}


	}

	// Unlock the database
	f_mutexUnlock( gv_FlmSysData.hShareMutex);

	// Begin rendering the page...
	stdHdr();

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

	// Determine if we are being requested to refresh this page or  not.

	if (bRefresh)
	{
		fnPrintf( m_pHRequest, 
			"<HEAD>"
			"<META http-equiv=\"refresh\" content=\"5; url=%s/SCacheHashTable?Start=%lu%s\">"
			"<TITLE>Database iMonitor - SCache Hash Table</TITLE>\n", m_pszURLString, uiStart, szRefresh);
	
	}
	else
	{
		fnPrintf( m_pHRequest, "<HEAD>\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/SCacheHashTable?Start=%lu&Refresh>Start Auto-refresh (5 sec.)</A>",
					 m_pszURLString, uiStart);
	}
	else
	{
		f_sprintf( (char *)pszTemp,
			       "<A HREF=%s/SCacheHashTable?Start=%lu>Stop Auto-refresh</A>",
					 m_pszURLString, uiStart);
	}

	// Print out a formal header and the refresh option.
	printTableStart("SCache Hash Table", 4);

	printTableRowStart();
	printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
	fnPrintf( m_pHRequest,
				 "<A HREF=%s/SCacheHashTable?Start=%lu%s>Refresh</A>, %s\n",
				 m_pszURLString, uiStart, szRefresh, pszTemp);
	printColumnHeadingClose();
	printTableRowEnd();
		
	printTableRowStart( (bHighlight = !bHighlight));
	fnPrintf( m_pHRequest, "<TD>Table Size: %lu </TD>\n", uiHashTableSize);
	printTableRowEnd();

	printTableRowStart( (bHighlight = !bHighlight));
	fnPrintf( m_pHRequest, "<TD>Entries Used: %lu (%lu%%) </TD>\n", uiUsedEntries,
				 ((uiUsedEntries * 100) / uiHashTableSize) );
	printTableRowEnd();
	
	// The rest of the table is going to be a single row with two columns:  
	// one for the list of hash buckets and the other for everything else

	printTableRowStart( FALSE);
	fnPrintf( m_pHRequest, " <TD>\n");
	// Print out the hash buckets
	for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
	{
		if (pszHTLinks[uiLoop][0] != '\0')
		{
			fnPrintf( m_pHRequest, "<A HREF=%s%s>%lu</A> <br>\n",
						 pszHTLinks[uiLoop], szRefresh, uiStart+uiLoop);
		}
		else
		{
			fnPrintf( m_pHRequest, "%lu<br>\n", uiStart+uiLoop);
		}
	}

	fnPrintf( m_pHRequest, "</ul>\n</TD>\n<TD>\n");

	// Print out the other stuff...
	uiNewStart = (uiStart > 100)?(uiStart - 100):0;
	fnPrintf( m_pHRequest, "<A HREF=%s/SCacheHashTable?Start=%lu%s>Previous 100</A> <BR>\n",
					m_pszURLString, uiNewStart, szRefresh);
	uiNewStart = (uiStart > 10)?(uiStart - 10):0;
	fnPrintf( m_pHRequest, "<A HREF=%s/SCacheHashTable?Start=%lu%s>Previous 10</A> <BR>\n",
					m_pszURLString, uiNewStart, szRefresh);

	fnPrintf( m_pHRequest, "<BR>\n");
	uiNewStart = (uiStart + 10);
	if (uiNewStart >= (uiHashTableSize - NUM_ENTRIES))
	{
		uiNewStart = (uiHashTableSize - NUM_ENTRIES);
	}
	fnPrintf( m_pHRequest, "<A HREF=%s/SCacheHashTable?Start=%lu%s>Next 10</A> <BR>\n",
					m_pszURLString, uiNewStart, szRefresh);

	uiNewStart = (uiStart + 100);
	if (uiNewStart >= (uiHashTableSize - NUM_ENTRIES))
	{
		uiNewStart = (uiHashTableSize - NUM_ENTRIES);
	}
	fnPrintf( m_pHRequest, "<A HREF=%s/SCacheHashTable?Start=%lu%s>Next 100</A> <BR>\n"
				"<form type=\"submit\" method=\"get\" action=\"/coredb/SCacheHashTable\">\n"
				"<BR> Jump to specific bucket:<BR> \n"
				"<INPUT type=\"text\" size=\"10\" maxlength=\"10\" name=\"Start\"></INPUT> <BR>\n",
				m_pszURLString, uiNewStart, szRefresh);
	printButton( "Jump", BT_Submit);
	// We use a hidden field to pass the refresh parameter back the the server
	if (bRefresh)
	{
		fnPrintf( m_pHRequest, "<INPUT type=\"hidden\" name=\"Refresh\"></INPUT>\n");
	}
	fnPrintf( m_pHRequest, "</form>\n</TD>\n");

	printTableRowEnd();

	printTableEnd();
	printDocEnd();
	fnEmit();

Exit:
	// Free the space for the hyperlink text
	for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
	{
		f_free( &pszHTLinks[uiLoop]);
	}

	f_free( &pszTemp);
	return( rc);

}
Пример #18
0
/****************************************************************************
Desc:	Store a data value into its vector element.
****************************************************************************/
RCODE F_DataVector::storeValue(
	FLMINT				uiElementNumber,
	FLMUINT				uiDataType,
	const FLMBYTE *	pucData,
	FLMUINT				uiDataLen,
	FLMBYTE **			ppucDataPtr)
{
	RCODE						rc = NE_XFLM_OK;
	F_VECTOR_ELEMENT *	pVector;
	FLMBYTE *				pucDataPtr;
	FLMUINT					uiTemp;

	// Find or allocate space for the vector

	if (RC_BAD( rc = allocVectorArray( uiElementNumber)))
	{
		goto Exit;
	}

	pVector = &m_pVectorElements [uiElementNumber];

	// Will the data fit inside uiDataOffset?

	if (uiDataLen <= sizeof( FLMUINT))
	{
		pucDataPtr = (FLMBYTE *)&pVector->uiDataOffset;
	}
	else if (uiDataLen <= pVector->uiDataLength)
	{

		// New data will fit in original space.  Simply reuse it.

		pucDataPtr = m_pucDataBuf + pVector->uiDataOffset;
	}
	else
	{

		// New data will not fit in originally allocated space.
		// Must allocate new space.

		// Always align the new allocation so that if it gets
		// reused later for binary data it will be properly aligned.

		if ((m_uiDataBufOffset & FLM_ALLOC_ALIGN) != 0)
		{
			uiTemp = (FLM_ALLOC_ALIGN + 1) - (m_uiDataBufOffset & FLM_ALLOC_ALIGN);
			m_uiDataBufOffset += uiTemp;
		}

		if (uiDataLen + m_uiDataBufOffset > m_uiDataBufLength)
		{
			// Re-allocate the data buffer.

			if( m_pucDataBuf == m_ucIntDataBuf)
			{
				if (RC_BAD( rc = f_alloc(
								m_uiDataBufOffset + uiDataLen + 512,
								&m_pucDataBuf)))
				{
					goto Exit;
				}

				f_memcpy( m_pucDataBuf, m_ucIntDataBuf, m_uiDataBufOffset);
			}
			else
			{
				if (RC_BAD( rc = f_realloc(
								m_uiDataBufOffset + uiDataLen + 512,
								&m_pucDataBuf)))
				{
					goto Exit;
				}
			}

			m_uiDataBufLength = m_uiDataBufOffset + uiDataLen + 512;
		}
		pucDataPtr = m_pucDataBuf + m_uiDataBufOffset;
		pVector->uiDataOffset = m_uiDataBufOffset;
		m_uiDataBufOffset += uiDataLen;
	}

	// Store the data - may be zero length.

	if( pucData)
	{
		if( uiDataLen > 1)
		{
			f_memcpy( pucDataPtr, pucData, uiDataLen);
		}
		else if( uiDataLen)
		{
			*pucDataPtr = *pucData;
		}
	}

	pVector->uiFlags |= VECT_SLOT_HAS_DATA;
	pVector->uiDataLength = uiDataLen;
	pVector->uiDataType = uiDataType;

	if( ppucDataPtr)
	{
		*ppucDataPtr = pucDataPtr;
	}

Exit:

	return( rc);
}
Пример #19
0
/****************************************************************************
Desc : Checks for physical corruption in a FLAIM database.
DNote: The routine verifies the database by first reading through
		 the database to count certain block types which are in linked lists.
		 It then verifies the linked lists.  It also verifies the B-TREEs
		 in the database.  The reason for the first pass is so that when we
		 verify the linked lists, we can keep ourselves from getting into
		 an infinite loop if there is a loop in the lists.
****************************************************************************/
RCODE F_DbCheck::dbCheck(
	const char *		pszDbFileName,
		// [IN] Full path and file name of the database which
		// is to be checked.  NULL can be passed as the value of
		// this parameter if pDb is non-NULL.
	const char *		pszDataDir,
		// [IN] Directory for data files.
	const char *		pszRflDir,
		// [IN] RFL directory.  NULL can be passed as the value of
		// this parameter to indicate that the log files are located
		// in the same directory as the database or if pDb is non-NULL.
	const char *		pszPassword,
		// [IN] Database password. Needed to open the database if the database
		// key has been wrapped in a password. NULL by default.
	FLMUINT				uiFlags,
		// [IN] Check flags.  Possible flags include:
		//
		//		XFLM_ONLINE. This flag instructs the check to repair any
		//		index corruptions it finds.  The database must have been
		//		opened in read/write mode in order for the check to
		//		successfully repair corruptions.  An update transaction
		//		will be started whenever a corruption is repaired.
		//
		//		XFLM_DO_LOGICAL_CHECK.  This flag instructs the check to
		//		perform a logical check of the databases's indexes
		//		in addition to the structural check.
		//
		//		XFLM_SKIP_DOM_LINK_CHECK.  This flag instructs the check to skip
		//		verifying the DOM links.  This check can take quite a long time
		//		to execute.
		//
		//		XFLM_ALLOW_LIMITED_MODE. This flag instructs the check to allow
		//		the database to be opened in limited mode if the database key is
		//		wrapped in a password and the password we pass is	incorrect 
		//		(or non-existent).
	IF_DbInfo **			ppDbInfo,
		// [IN] Pointer to a DB_INFO structure which is used to store
		// statistics collected during the database check.
	IF_DbCheckStatus *	pDbCheckStatus
		// [IN] Status interface.  Functions in this interface are called 
		// periodically to iform the calling application of the progress
		// being made.  This allows the application to monitor and/or display
		// the progress of the database check.  NULL may be passed as the
		// value of this parameter if the callback feature is not needed.
	)
{
	RCODE								rc = NE_XFLM_OK;
	FLMBYTE *						pBlk = NULL;
	FLMUINT							uiFileEnd;
	FLMUINT							uiBlockSize;
	FLMUINT							uiLoop;
	FLMUINT64						ui64TmpSize;
	FLMBOOL							bStartOver;
	FLMBOOL							bOkToCloseTrans = FALSE;
	FLMBOOL							bAllowLimitedMode =  ( uiFlags & XFLM_ALLOW_LIMITED_MODE)
																		? TRUE
																		: FALSE;

	if (RC_BAD( rc = gv_pXFlmDbSystem->dbOpen( pszDbFileName, pszDataDir,
		pszRflDir, pszPassword, bAllowLimitedMode, (IF_Db **)&m_pDb)))
	{
		goto Exit;
	}

	if ((m_pDbInfo = f_new F_DbInfo) == NULL)
	{
		rc = RC_SET( NE_XFLM_MEM);
		goto Exit;
	}
	if (ppDbInfo)
	{
		*ppDbInfo = m_pDbInfo;
		(*ppDbInfo)->AddRef();
	}

	m_pDbCheckStatus = pDbCheckStatus;
	m_LastStatusRc = NE_XFLM_OK;

	// Get the file size...

	if (uiFlags & XFLM_SKIP_DOM_LINK_CHECK)
	{
		m_bSkipDOMLinkCheck = TRUE;
	}

	// Initialize the information block and Progress structure.

	// Since we know that the check will start read transactions
	// during its processing, set the flag to indicate that the KRef table
	// should be cleaned up on exit if we are still in a read transaction.

	bOkToCloseTrans = TRUE;
	uiBlockSize = m_pDb->m_pDatabase->getBlockSize();

	// Allocate memory to use for reading through the data blocks.

	if( RC_BAD( rc = f_alloc( uiBlockSize, &pBlk)))
	{
		goto Exit;
	}

	if ((m_pBtPool = f_new F_BtPool) == NULL)
	{
		rc = RC_SET( NE_XFLM_MEM);
		goto Exit;
	}

	if (RC_BAD( rc = m_pBtPool->btpInit()))
	{
		goto Exit;
	}
	
	// Setup the result set database.
	
	if( RC_BAD( rc = FlmAllocRandomGenerator( &m_pRandGen)))
	{
		goto Exit;
	}

	m_pRandGen->setSeed( 9768);

	if (RC_BAD( rc = createAndOpenResultSetDb()))
	{
		goto Exit;
	}

Begin_Check:

	// Initialize all statistics in the DB_INFO structure.

	rc = NE_XFLM_OK;
	bStartOver = FALSE;

	m_pDbInfo->m_ui64FileSize = 0;
	m_pDbInfo->freeLogicalFiles();
	m_bPhysicalCorrupt = FALSE;
	m_bIndexCorrupt = FALSE;
	m_uiFlags = uiFlags;
	m_bStartedUpdateTrans = FALSE;
	f_memset( &m_pDbInfo->m_AvailBlocks, 0, sizeof( BLOCK_INFO));
	f_memset( &m_pDbInfo->m_LFHBlocks, 0, sizeof( BLOCK_INFO));

	f_memset( &m_Progress, 0, sizeof( XFLM_PROGRESS_CHECK_INFO));

	/* Get the dictionary information for the file. */

	if (RC_BAD( rc = getDictInfo()))
	{
		goto Exit;
	}

	m_Progress.ui64BytesExamined = 0;

	for (uiLoop = 1;
		  uiLoop <= MAX_DATA_BLOCK_FILE_NUMBER;
		  uiLoop++)
	{
		if (RC_BAD( m_pDb->m_pSFileHdl->getFileSize( uiLoop, &ui64TmpSize)))
		{
			break;
		}
		
		m_Progress.ui64FileSize += ui64TmpSize;
	}

	// See if we have a valid end of file

	uiFileEnd = m_pDb->m_uiLogicalEOF;
	if (FSGetFileOffset( uiFileEnd) % uiBlockSize != 0)
	{
		if (RC_BAD( rc = chkReportError( FLM_BAD_FILE_SIZE, XFLM_LOCALE_NONE,
			0, 0, 0xFF, (FLMUINT32)uiFileEnd, 0, 0, 0)))
		{
			goto Exit;
		}
	}
	else if (m_Progress.ui64FileSize <
					FSGetSizeInBytes( m_pDb->m_pDatabase-> getMaxFileSize(),
																		uiFileEnd))
	{
		m_Progress.ui64FileSize =
					FSGetSizeInBytes( m_pDb->m_pDatabase->getMaxFileSize(),
																uiFileEnd);
	}

	m_pDbInfo->m_ui64FileSize = m_Progress.ui64FileSize;

	// Verify the LFH blocks, B-Trees, and the AVAIL list.

	if( RC_BAD( rc = verifyLFHBlocks( &bStartOver)))
	{
		goto Exit;
	}
	if (bStartOver)
	{
		goto Begin_Check;
	}

	// Check the b-trees.
	
	if (RC_BAD( rc = verifyBTrees( &bStartOver)))
	{
		goto Exit;
	}
	if (bStartOver)
	{
		goto Begin_Check;
	}

	// Check the avail list.

	if (RC_BAD( rc = verifyAvailList( &bStartOver)))
	{
		goto Exit;
	}
	if (bStartOver)
	{
		goto Begin_Check;
	}

Exit:

	if ((m_bPhysicalCorrupt || m_bIndexCorrupt) &&
		 !gv_pXFlmDbSystem->errorIsFileCorrupt( rc))
	{
		rc = RC_SET( NE_XFLM_DATA_ERROR);
	}

	if (RC_OK( rc) && RC_BAD( m_LastStatusRc))
	{
		rc = m_LastStatusRc;
	}

	if (m_pDb)
	{
		// Close down the transaction, if one is going

		if( bOkToCloseTrans &&
			m_pDb->getTransType( ) == XFLM_READ_TRANS)
		{
			m_pDb->krefCntrlFree();
			m_pDb->transAbort();
		}
	}
	
	// Free memory, if allocated

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

	// Close the FLAIM database we opened.

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

	return( rc);
}
Пример #20
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);
}
Пример #21
0
/****************************************************************************
Desc:	This is the function that the HTTP server calls when it wants to
			display one of our pages
****************************************************************************/
int flmHttpCallback(
	HRequest *			pHRequest,
	void *				//pvUserData
	)
{
	RCODE							rc = FERR_OK;
	F_WebPage *					pPage = NULL;
	char *						pszPath = NULL;
	char *						pszQuery = NULL;
	char *						pszTemp = NULL;
	const char *				pszConstTemp = NULL;
#define MAX_PARAMS 10
	const char *				pszParams[ MAX_PARAMS];
	FLMUINT						uiNumParams;

	// If we get a NULL for the pHRequest object, then we are shutting down...

	if (pHRequest == NULL)
	{
		// Remove the globals that enable the secure pages...
		gv_FlmSysData.HttpConfigParms.fnSetGblValue( 
				FLM_SECURE_PASSWORD, "", 0);
		gv_FlmSysData.HttpConfigParms.fnSetGblValue(
				FLM_SECURE_EXPIRATION, "", 0);

		// Delete the web page factory object
		if (gv_pWPFact)
		{
			gv_pWPFact->Release( NULL);
		}
		gv_pWPFact = NULL;
		goto Exit;
	}

	// Increment the use count (helps ensure that the function pointers
	// that display() references don't go away while display() still needs
	// them.

	f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
	gv_FlmSysData.HttpConfigParms.uiUseCount++;
	f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);

	// Must not access any HRequest function pointers prior to incrementing the
	// use count.

	if( !gv_FlmSysData.HttpConfigParms.fnReqPath)
	{
		flmAssert( 0);
		rc = RC_SET( FERR_FAILURE);
		goto Exit;
	}

	// If the web page factory does not exist yet, then we need to create it.
	if (!gv_pWPFact)
	{
		f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
		// In the time it took us to get the lock, some other thread might
		// have come along and created the factory already...
		if (!gv_pWPFact)
		{
			if ((gv_pWPFact = f_new F_WebPageFactory) == NULL)
			{
				rc = RC_SET( FERR_MEM);
				f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
				goto Exit;
			}
		}
		f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
	}
	
	pszConstTemp = gv_FlmSysData.HttpConfigParms.fnReqPath( pHRequest);
	flmAssert( pszConstTemp);

	if( RC_BAD( rc = f_alloc( 
		f_strlen( pszConstTemp) + 1, &pszPath)))
	{
		goto Exit;
	}

	f_strcpy( pszPath, pszConstTemp);
	
	pszConstTemp = gv_FlmSysData.HttpConfigParms.fnReqQuery( pHRequest);
	if( pszConstTemp)
	{
		if( RC_BAD( rc = f_alloc( f_strlen( pszConstTemp) + 1, &pszQuery)))
		{
			goto Exit;
		}

		f_strcpy( pszQuery, pszConstTemp);
		pszConstTemp = pszQuery;
	}
	else  // This URL had no query string...
	{
		// If pszQuery is NULL, it causes problems further down, so we'll
		// make it a pointer to a null string...

		if( RC_BAD( rc = f_alloc( 1, &pszQuery)))
		{
			goto Exit;
		}
		pszQuery[0] = '\0';				
	}

	// Strip off pszURLString (and the next '/', if there is one) from the request and store 
	// what's left as pszParams[0].
	// (ie: /coredb/FlmSysData --> FlmSysData)

	// Note: The reason we're checking for the URL string first is because if
	// we're using our own http stack, then this callback is called for every
	// http request and we don't want to crash if we've got a short URI.
	// When we're running under DS, we're guarenteed that the URLString will
	// be part of the URI.

	if( f_strlen( pszPath) >= gv_FlmSysData.HttpConfigParms.uiURLStringLen)
	{
		pszConstTemp = pszPath + gv_FlmSysData.HttpConfigParms.uiURLStringLen;
		if( *pszConstTemp == '/')
		{
			pszConstTemp++;
		}
	}
	else
	{
		pszConstTemp = pszPath;
	}

	pszParams[0] = pszConstTemp;
	uiNumParams = 1;


	// Parse parameters in the query string 
	// Note that it's technically incorrect to have more than one ? in a
	// URL, but we didn't know that when we first started creating some of 
	// these pages and as a result, some queries are in the form of:
	// ?name1=value1?name2=value2?name3=value3...  (which is improper) and
	// some have the form:
	// ?name1=value1&name2=value2&name3=value3... (which is correct).
	
	pszTemp = pszQuery;
	
	while( *pszTemp != 0)
	{
		flmAssert( uiNumParams < MAX_PARAMS);
		pszParams[ uiNumParams] = pszTemp;
		uiNumParams++;
		
		pszTemp = tokenizer( pszTemp, '?', '&');
		
		if (*pszTemp)
		{
			*pszTemp = '\0';
			pszTemp++;
		}
	}

	// Tell the factory to create the page
	
	if (RC_BAD( rc = gv_pWPFact->create( pszParams[0], &pPage, pHRequest)))
	{
		goto Exit;
	}
	
	
	pPage->setMembers( pHRequest);

	// display the page
	if( RC_BAD( rc = pPage->display (uiNumParams, &pszParams[0])))
	{
		goto Exit;
	}

Exit:

	// Decrement the use count

	if( pHRequest)
	{
		f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
		if( gv_FlmSysData.HttpConfigParms.uiUseCount > 0)
		{
			gv_FlmSysData.HttpConfigParms.uiUseCount--;
		}
		else
		{
			flmAssert( 0);
		}
		f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
	}
	
	if (pPage)
	{
		gv_pWPFact->Release( &pPage);
	}

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

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

	return (int)rc;
}
Пример #22
0
errno_t
sc_open(thread_t *p, syscall_result_t *r, sc_open_args *arg)
{
    int fd;
    int flags = arg->flags;
    int error = 0;
    vnode_t *node;
    proc_t *proc = p->thr_proc;
    char fname[PATH_MAX+1];
    if((error = copyinstr(fname, arg->fname, PATH_MAX)))
        return error;
    KASSERT(proc->p_rootdir!=NULL);
    error = vfs_lookup(proc->p_curdir, &node, fname, p, LKP_NORMAL);
    if(error) {
        if(!(flags & O_CREAT))
            return error;
        vnode_t *parent;
        error = vfs_lookup_parent(proc->p_curdir, &parent, fname, p);
        if(error)
            return error;
        if((error = VOP_ACCESS(parent, W_OK, proc->p_cred))) {
            vrele(parent);
            return error;
        }
        vattr_t attr;
        attr.va_mode = arg->mode & ~(proc->p_umask) & 0777;
        attr.va_type = VNODE_TYPE_REG;
        attr.va_uid = proc->p_cred->p_uid;
        attr.va_gid = proc->p_cred->p_gid;
        attr.va_size = 0;
        attr.va_dev = NULL;
        error = VOP_CREATE(parent, &node, _get_last_cmpt(fname), &attr);
        VOP_UNLOCK(parent);
        if(error)
            return error;
        VOP_LOCK(node);
    } else {
        //plik istnieje
        if((flags & O_CREAT) && (flags & O_EXCL)) {
            vrele(node);
            return -EEXIST;
        }
        if((node->v_type == VNODE_TYPE_DIR) && (flags & (O_RDWR | O_WRONLY))) {
            vrele(node);
            return -EISDIR;
        }
    }
    int wmode = (flags & O_RDWR) ? (W_OK | R_OK) :
                (flags & O_RDONLY) ? (R_OK) : (W_OK);
    if((error = VOP_ACCESS(node, wmode, proc->p_cred))) {
        vrele(node);
        return error;
    }
    if((error = VOP_OPEN(node, flags, arg->mode))) {
        vrele(node);
        return error;
    }
    if(ISSET(flags, O_RDWR | O_WRONLY) && ISSET(flags, O_TRUNC)
       && node->v_type == VNODE_TYPE_REG)
        VOP_TRUNCATE(node, 0);

    if((error = f_alloc(proc, node, flags, &fd))) {
        vrele(node); // <- powinno to tutaj być, dopisałem bo nie było.
        return error;
    }
    VOP_UNLOCK(node);
    r->result = fd;
    return 0;
}
Пример #23
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);
}
Пример #24
0
/****************************************************************************
Desc: This routine sets up a new F_Database object, allocating member
		variables, linking into lists, etc.
		NOTE: This routine assumes that the global mutex has already
		been locked. It may unlock it temporarily if there is an error,
		but will always relock it before exiting.
****************************************************************************/
RCODE F_Database::setupDatabase(
	const char *		pszDbPath,
	const char *		pszDataDir)
{
	RCODE				rc = NE_XFLM_OK;
	FLMUINT			uiAllocLen;
	FLMUINT			uiDbNameLen;
	FLMUINT			uiDirNameLen;
	char				szDbPathStr[ F_PATH_MAX_SIZE];
	char				szDataDirStr[ F_PATH_MAX_SIZE];

	if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString( 
		pszDbPath, szDbPathStr)))
	{
		goto Exit;
	}
	uiDbNameLen = f_strlen( szDbPathStr) + 1;

	if( pszDataDir && *pszDataDir)
	{
		if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString( 
			pszDataDir, szDataDirStr)))
		{
			goto Exit;
		}
		uiDirNameLen = f_strlen( szDataDirStr) + 1;

	}
	else
	{
		szDataDirStr[0] = 0;
		uiDirNameLen = 0;
	}

	
	if (RC_BAD( rc = f_mutexCreate( &m_hMutex)))
	{
		goto Exit;
	}


	uiAllocLen = (FLMUINT)(uiDbNameLen + uiDirNameLen);
	if (RC_BAD( rc = f_alloc( uiAllocLen, &m_pszDbPath)))
	{
		goto Exit;
	}
	
	// Allocate a buffer for writing the DB header
	// If we are a temporary database, there is no need
	// for this allocation.

	if (!m_bTempDb)
	{
		if( RC_BAD( rc = f_allocAlignedBuffer( 
			XFLM_MAX_BLOCK_SIZE, (void **)&m_pDbHdrWriteBuf)))
		{
			goto Exit;
		}
	}

	// Setup the write buffer managers.
	
	if( RC_BAD( rc = FlmAllocIOBufferMgr( MAX_PENDING_WRITES,
		MAX_WRITE_BUFFER_BYTES, FALSE, &m_pBufferMgr)))
	{
		goto Exit;
	}

	// Initialize members of F_Database object.

	m_uiBucket = 0xFFFF;
	m_uiFlags = DBF_BEING_OPENED;

	// Copy the database name and directory.
	// NOTE: uiDbNameLen includes the null terminating byte.
	// and uiDirNameLen includes the null terminating byte.

	f_memcpy( m_pszDbPath, szDbPathStr, uiDbNameLen);
	if (uiDirNameLen)
	{
		m_pszDataDir = m_pszDbPath + uiDbNameLen;
		f_memcpy( m_pszDataDir, szDataDirStr, uiDirNameLen);
	}

	// Link the file into the various lists it needs to be linked into.

	if (RC_BAD( rc = linkToBucket()))
	{
		goto Exit;
	}

	// Allocate a lock object for write locking.
	
	if( RC_BAD( rc = FlmAllocLockObject( &m_pWriteLockObj)))
	{
		goto Exit;
	}

	// Allocate a lock object for file locking.
	
	if( RC_BAD( rc = FlmAllocLockObject( &m_pDatabaseLockObj)))
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #25
0
/***************************************************************************
Desc: This routine reads the header information for an existing
		flaim database and makes sure we have a valid database.
*****************************************************************************/
RCODE F_Database::readDbHdr(
	const char *			pszDbPath,
	XFLM_DB_STATS *		pDbStats,
	FLMBYTE *				pszPassword,
	FLMBOOL					bAllowLimited)
{
	RCODE						rc = NE_XFLM_OK;
	IF_FileHdl *			pFileHdl = NULL;

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

	// Read and verify the database header.

	if (RC_BAD( rc = flmReadAndVerifyHdrInfo( pDbStats, pFileHdl,
									&m_lastCommittedDbHdr)))
	{
		goto Exit;
	}
	
	m_uiBlockSize = (FLMUINT)m_lastCommittedDbHdr.ui16BlockSize;
	m_uiDefaultLanguage = (FLMUINT)m_lastCommittedDbHdr.ui8DefaultLanguage;
	m_uiMaxFileSize = (FLMUINT)m_lastCommittedDbHdr.ui32MaxFileSize;
	m_uiSigBitsInBlkSize = calcSigBits( m_uiBlockSize);

	// Initialize the master database key from the database header
	
	m_bAllowLimitedMode = bAllowLimited;

	if (pszPassword && *pszPassword)
	{
		if (m_pszDbPasswd)
		{
			f_free( &m_pszDbPasswd);
		}

		if ( RC_BAD( rc = f_alloc( 
			(f_strlen( (const char *)pszPassword) + 1), &m_pszDbPasswd)))
		{
			goto Exit;
		}
		
		f_strcpy( (char *)m_pszDbPasswd, (const char *)pszPassword);
	}
	
	if( RC_BAD( rc = flmAllocCCS( &m_pWrappingKey)))
	{
		goto Exit;
	}

	if( RC_OK( rc = m_pWrappingKey->init( TRUE, FLM_NICI_AES)))
	{
		// If the key was encrypted in a password, then the pszPassword parameter better
		// be the key used to encrypt it.  If the key was not encrypted in a password,
		// then pszPassword parameter should be NULL.

		rc = m_pWrappingKey->setKeyFromStore(
								m_lastCommittedDbHdr.DbKey,
								pszPassword, NULL);
	}
	
	if( RC_BAD( rc))
	{
		if ((rc == NE_XFLM_ENCRYPTION_UNAVAILABLE) || bAllowLimited)
		{
			m_bInLimitedMode = TRUE;
			rc = NE_XFLM_OK;
		}
		else
		{
			goto Exit;
		}
	}

	// Note that we might still end up in limited mode if we can't verify all the keys
	// that are stored in the dictionary.

Exit:

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

	return( rc);
}
Пример #26
0
/****************************************************************************
Desc:	Setup routine for the KREF_CNTRL structure for record updates.
****************************************************************************/
RCODE F_Db::krefCntrlCheck( void)
{
	RCODE	rc = NE_SFLM_OK;

	// Check if we need to flush keys between updates, but not during the
	// processing of an update.

	if( m_bKrefSetup)
	{
		if (isKrefOverThreshold())
		{
			if (RC_BAD( rc = keysCommit( FALSE)))
			{
				goto Exit;
			}
		}
	}
	else
	{
		m_uiKrefCount = 0;
		m_uiTotalKrefBytes = 0;
		m_pKrefPool = NULL;
		m_bReuseKrefPool = FALSE;
		m_bKrefCompoundKey = FALSE;
		m_pKrefReset = NULL;
		m_bKrefSetup = TRUE;

		if (m_eTransType == SFLM_UPDATE_TRANS)
		{
			m_pKrefPool = &m_pDatabase->m_krefPool;
			
			m_bReuseKrefPool = TRUE;
			m_pKrefPool->poolReset( NULL, TRUE);
		}
		else
		{
			m_tmpKrefPool.poolFree();
			m_tmpKrefPool.poolInit( DEFAULT_KREF_POOL_BLOCK_SIZE);
			m_pKrefPool = &m_tmpKrefPool;
			
			m_bReuseKrefPool = FALSE;
		}

		if( !m_pKrefTbl)
		{
			if( RC_BAD( rc = f_alloc( 
				DEFAULT_KREF_TBL_SIZE * sizeof( KREF_ENTRY *), &m_pKrefTbl)))
			{
				goto Exit;
			}

			m_uiKrefTblSize = DEFAULT_KREF_TBL_SIZE;
		}
		
		if( !m_pucKrefKeyBuf)
		{
			if (RC_BAD( rc = f_alloc( SFLM_MAX_KEY_SIZE, &m_pucKrefKeyBuf)))
			{
				goto Exit;
			}
		}
	}

	m_pKrefReset = m_pKrefPool->poolMark();
	flmAssert( m_pucKrefKeyBuf);

Exit:

	if (RC_BAD( rc))
	{
		krefCntrlFree();
	}

	return( rc);
}
Пример #27
0
/****************************************************************************
Name:	insert
Desc:
*****************************************************************************/
RCODE F_DynamicList::insert(
	FLMUINT					uiKey,
	F_DLIST_DISP_HOOK 	pDisplayHook,
	void *					pvData,
	FLMUINT					uiDataLen)
{
	RCODE				rc = NE_FLM_OK;
	DLIST_NODE *	pTmp;
	DLIST_NODE *	pNew = NULL;

	if( getNode( uiKey) != NULL)
	{
		rc = RC_SET( NE_FLM_EXISTS);
		goto Exit;
	}

	// Allocate the new node

	if( RC_BAD( rc = f_alloc( sizeof( DLIST_NODE), &pNew)))
	{
		goto Exit;
	}

	f_memset( pNew, 0, sizeof( DLIST_NODE));

	// Set the members of the new node

	pNew->uiKey = uiKey;

	if( pDisplayHook)
	{
		pNew->pDispHook = pDisplayHook;
	}
	else
	{
		pNew->pDispHook = dlistDefaultDisplayHook;
	}

	if( uiDataLen)
	{
		if( RC_BAD( rc = f_alloc( uiDataLen, &pNew->pvData)))
		{
			goto Exit;
		}

		f_memcpy( pNew->pvData, pvData, uiDataLen);
		pNew->uiDataLen = uiDataLen;
	}

	// Find the insertion point

	if( !m_pFirst)
	{
		m_pFirst = m_pLast = m_pCur = pNew;
	}
	else
	{
		pTmp = m_pFirst;
		while( pTmp && pTmp->uiKey < uiKey)
		{
			pTmp = pTmp->pNext;
		}

		if( pTmp)
		{
			if( pTmp == m_pFirst)
			{
				pNew->pNext = m_pFirst;
				m_pFirst->pPrev = pNew;
				m_pFirst = pNew;
			}
			else
			{
				pNew->pNext = pTmp;
				pNew->pPrev = pTmp->pPrev;

				if( pTmp->pPrev)
				{
					pTmp->pPrev->pNext = pNew;
				}

				pTmp->pPrev = pNew;
			}
		}
		else
		{
			// Insert at end
			m_pLast->pNext = pNew;
			pNew->pPrev = m_pLast;
			m_pLast = pNew;
		}
	}

	m_bChanged = TRUE;

Exit:

	if( RC_BAD( rc))
	{
		if( pNew)
		{
			freeNode( pNew);
		}
	}

	return( rc);
}
Пример #28
0
/****************************************************************************
Desc:	Prints the web page for an SCACHE struct
****************************************************************************/
RCODE F_SCacheBlockPage::display(
	FLMUINT			uiNumParams,
	const char ** 	ppszParams)
{
	RCODE				rc = FERR_OK;
	FLMUINT			uiBlkAddress = 0;
	FLMUINT			uiLowTransID = 0;
	FLMUINT			uiHighTransID = 0;
	FFILE *			pFile;
	FLMBOOL			bHighlight = FALSE;
	char *			pszTemp = NULL;
	char *			pszTemp1 = NULL;
	FLMUINT			uiLoop = 0;
	char				szOffsetTable[10][6];
	char				szAddressTable[4][20];
	SCACHE			LocalSCacheBlock;
	FLMUINT			uiPFileBucket = 0;
	char *			pszSCacheRequestString[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	char *			pszSCacheDataRequest = NULL;
	char *			pszSCacheAutoRequest = NULL; 
	char *			pszSCacheUseListRequest = NULL;
	char *			pszSCacheNotifyListRequest = NULL;
	char *			pszFFileRequest = NULL;
	char *			pszFlagNames = NULL;

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

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

	// Allocate memory for all those string pointers we declared above...
	for (uiLoop = 0; uiLoop < 8; uiLoop++)
	{
		if( RC_BAD( rc = f_alloc( 150, &pszSCacheRequestString[ uiLoop])))
		{
			goto Exit;
		}
	}
		
	if( RC_BAD( rc = f_alloc( 150, &pszSCacheDataRequest)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 150, &pszSCacheAutoRequest)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 150, &pszSCacheUseListRequest)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 150, &pszSCacheNotifyListRequest)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 100, &pszFFileRequest)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = f_alloc( 100, &pszFlagNames)))
	{
		goto Exit;
	}

	f_mutexLock( gv_FlmSysData.hShareMutex);

	rc = locateSCacheBlock( uiNumParams, ppszParams, &LocalSCacheBlock,
									&uiBlkAddress, &uiLowTransID,	&uiHighTransID,
									&pFile);

	if (RC_OK(rc) && LocalSCacheBlock.pFile)
	{
		uiPFileBucket = LocalSCacheBlock.pFile->uiBucket;
	}

	
	if (RC_OK( rc))
	{
		// Build the proper strings to request various other SCache blocks
		flmBuildSCacheBlockString( pszSCacheRequestString[0], LocalSCacheBlock.pPrevInFile);
		flmBuildSCacheBlockString( pszSCacheRequestString[1], LocalSCacheBlock.pNextInFile);
		flmBuildSCacheBlockString( pszSCacheRequestString[2], LocalSCacheBlock.pPrevInGlobalList);
		flmBuildSCacheBlockString( pszSCacheRequestString[3], LocalSCacheBlock.pNextInGlobalList);
		flmBuildSCacheBlockString( pszSCacheRequestString[4], LocalSCacheBlock.pPrevInHashBucket);
		flmBuildSCacheBlockString( pszSCacheRequestString[5], LocalSCacheBlock.pNextInHashBucket);
		flmBuildSCacheBlockString( pszSCacheRequestString[6], LocalSCacheBlock.pPrevInVersionList);
		flmBuildSCacheBlockString( pszSCacheRequestString[7], LocalSCacheBlock.pNextInVersionList);

		// Build the proper string to request the current Page
		flmBuildSCacheBlockString( pszSCacheAutoRequest, &LocalSCacheBlock);
	}

	f_mutexUnlock( gv_FlmSysData.hShareMutex);

	if (RC_BAD( rc))
	{
		if (rc == FERR_NOT_FOUND)
		{
			
			// The block wasn't there, print an error message and exit
			notFoundErr();
			rc = FERR_OK;
		}
		else if (rc == FERR_MEM)
		{
			// Parameters were too long to store in the space provided.
			// Probably means that the URL was malformed...
			malformedUrlErr();
			rc = FERR_OK;
		}
		goto Exit;
	}
	
	//Build the proper string to request this block's data...
	printAddress( pFile, szAddressTable[0]);
	f_sprintf( (char *)pszSCacheDataRequest,
		"%s/SCacheData?BlockAddress=%lu&File=%s&LowTransID=%lu&HighTransID=%lu",
		m_pszURLString, LocalSCacheBlock.uiBlkAddress, szAddressTable[0],
		uiLowTransID, uiHighTransID);
	
#ifdef FLM_DEBUG
	//Build the proper string to request this block's use list
	if( LocalSCacheBlock.pUseList)
	{
		f_sprintf( (char *)pszSCacheUseListRequest,
			"%s/SCacheUseList?BlockAddress=%lu&File=%s&LowTransID=%lu&HighTransID=%lu",
			m_pszURLString, LocalSCacheBlock.uiBlkAddress, szAddressTable[0],
			uiLowTransID, uiHighTransID);
	}
	else
	{
		pszSCacheUseListRequest[0] = '\0';
	}
#endif

	//Build the proper string to request the notify list data...
	if (LocalSCacheBlock.pNotifyList)
	{
		f_sprintf( (char *)pszSCacheNotifyListRequest,
			"%s/SCacheNotifyList?BlockAddress=%lu&File=%s&LowTransID=%lu&HighTransID=%lu",
			m_pszURLString, LocalSCacheBlock.uiBlkAddress, szAddressTable[0],
			uiLowTransID, uiHighTransID);
	}
	else
	{
		pszSCacheNotifyListRequest[0] = '\0';
	}

	//Build the proper string to request the FFile
	printAddress( LocalSCacheBlock.pFile, szAddressTable[0]);
	f_sprintf( (char *)pszFFileRequest, "%s/FFile?From=SCacheBlock&Bucket=%lu&Address=%s",
				 m_pszURLString, uiPFileBucket, szAddressTable[0]);
					

	// Build a string with the names of all the flags that have been set...
	pszFlagNames[0]='\0';
	if (LocalSCacheBlock.ui16Flags & CA_DIRTY)
	{
		f_strcat( pszFlagNames, "<BR> CA_DIRTY");
	}
	if (LocalSCacheBlock.ui16Flags & CA_READ_PENDING)
	{
		f_strcat( pszFlagNames, "<BR> CA_READ_PENDING");
	}
	if (LocalSCacheBlock.ui16Flags & CA_WRITE_TO_LOG)
	{
		f_strcat( pszFlagNames, "<BR> CA_WRITE_TO_LOG");
	}
	if (LocalSCacheBlock.ui16Flags & CA_LOG_FOR_CP)
	{
		f_strcat( pszFlagNames, "<BR> CA_LOG_FOR_CP");
	}
	if (LocalSCacheBlock.ui16Flags & CA_WAS_DIRTY)
	{
		f_strcat( pszFlagNames, "<BR> CA_WAS_DIRTY");
	}
	if (LocalSCacheBlock.ui16Flags & CA_WRITE_PENDING)
	{
		f_strcat( pszFlagNames, "<BR> CA_WRITE_PENDING");
	}
	if (LocalSCacheBlock.ui16Flags & CA_IN_WRITE_PENDING_LIST)
	{
		f_strcat( pszFlagNames, "<BR> CA_IN_WRITE_PENDING_LIST");
	}


	// OK - Start outputting HTML...
	stdHdr();

	fnPrintf( m_pHRequest, HTML_DOCTYPE "<html>\n");
		
	// Determine if we are being requested to refresh this page or  not.
	if (DetectParameter( uiNumParams, ppszParams, "Refresh"))
	{
		// Send back the page with a refresh command in the header
		fnPrintf( m_pHRequest, 
			"<HEAD>\n"
			"<META http-equiv=\"refresh\" content=\"5; url=\"%s\">"
			"<TITLE>SCache Block</TITLE>\n", pszSCacheAutoRequest);
		printStyle();
		popupFrame();  //Spits out a Javascript function that will open a new window..
		fnPrintf( m_pHRequest, "</HEAD>\n<body>\n");
		
		f_sprintf( (char*)pszTemp,
					"<A HREF=\"%s\">Stop Auto-refresh</A>", pszSCacheAutoRequest);
	}
	else
	{
		// Send back a page without the refresh command
		
		fnPrintf( m_pHRequest, "<HEAD>\n");
		printStyle();
		popupFrame();  //Spits out a Javascript function that will open a new window..
		fnPrintf( m_pHRequest, "</HEAD>\n<body>\n");
		
		f_sprintf( (char *)pszTemp,
					"<A HREF=\"%s?Refresh\">Start Auto-refresh (5 sec.)</A>", pszSCacheAutoRequest);
	}

	// Write out the table headings
	printTableStart( "SCache Block Structure", 4, 100);

	printTableRowStart();
	printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
	fnPrintf( m_pHRequest, "<A HREF=\"%s\">Refresh</A>, %s\n",
				 pszSCacheAutoRequest, pszTemp);
	printColumnHeadingClose();
	printTableRowEnd();

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

	// Print the two rows for pPrevInFile and pNextInFile
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[0], "pPrevInFile", &LocalSCacheBlock, &LocalSCacheBlock.pPrevInFile);
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[1], "pNextInFile", &LocalSCacheBlock, &LocalSCacheBlock.pNextInFile);


	// Format the strings that are displayed in the Offset and Address
	// columns of the table
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.pucBlk, szOffsetTable[0]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.pFile, szOffsetTable[1]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.uiBlkAddress, szOffsetTable[2]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.pNotifyList, szOffsetTable[3]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.uiHighTransID, szOffsetTable[4]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.uiUseCount, szOffsetTable[5]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.ui16Flags, szOffsetTable[6]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.ui16BlkSize, szOffsetTable[7]);
#ifdef FLM_DEBUG
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.uiChecksum, szOffsetTable[8]);
	printOffset( &LocalSCacheBlock, &LocalSCacheBlock.pUseList, szOffsetTable[9]);
#endif

	printAddress( LocalSCacheBlock.pucBlk, szAddressTable[0]);
	printAddress( LocalSCacheBlock.pFile, szAddressTable[1]);
	printAddress( LocalSCacheBlock.pNotifyList, szAddressTable[2]);
#ifdef FLM_DEBUG
	printAddress( LocalSCacheBlock.pUseList, szAddressTable[3]);
#endif


	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td><A HREF=\"javascript:openPopup('%s')\">pucBlk</A></td>\n"
				"<td>FLMBYTE *</td>\n<td><A HREF=\"javascript:openPopup('%s')\">%s</A></td>\n",
				szOffsetTable[0],	pszSCacheDataRequest, pszSCacheDataRequest, szAddressTable[0] );
	printTableRowEnd();

	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td><A href=%s>pFile</A></td>\n"
				"<td>FFILE *</td>\n<td><A HREF=%s>%s</a></td>\n",
				szOffsetTable[1], pszFFileRequest, pszFFileRequest, szAddressTable[1]);
	printTableRowEnd();

	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>uiBlkAddress</td>\n<td>FLMUINT</td>\n"
				"<td>0x%lX</td>\n", szOffsetTable[2], LocalSCacheBlock.uiBlkAddress);
	printTableRowEnd();

	//Print the rows for the remaining SCache * fields
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[2], "pPrevInGlobalList", &LocalSCacheBlock, &LocalSCacheBlock.pPrevInGlobalList);		
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[3], "pNextInGlobalList", &LocalSCacheBlock, &LocalSCacheBlock.pNextInGlobalList);
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[4], "pPrevInHashBucket", &LocalSCacheBlock, &LocalSCacheBlock.pPrevInHashBucket);		
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[5], "pNextInHashBucket", &LocalSCacheBlock, &LocalSCacheBlock.pNextInHashBucket);
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[6], "pPrevInVersionList", &LocalSCacheBlock, &LocalSCacheBlock.pPrevInVersionList);		
	printTableRowStart( bHighlight = ~bHighlight);
	flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[7], "pNextInVersionList", &LocalSCacheBlock, &LocalSCacheBlock.pNextInVersionList);

	//Notify list line
	printTableRowStart( bHighlight = ~bHighlight);
	if (LocalSCacheBlock.pNotifyList)
	{
		fnPrintf( m_pHRequest,
			TD_s
			" <td> <A HREF=\"javascript:openPopup('%s')\"> pNotifyList </A> </td>	<td>FNOTIFY *</td> "
			"<td> <A HREF=\"javascript:openPopup('%s')\"> %s </A> </td>",
			szOffsetTable[3], pszSCacheNotifyListRequest,
			pszSCacheNotifyListRequest, szAddressTable[2]);
	}
	else
	{
		fnPrintf( m_pHRequest,
			TD_s " <td> pNotifyList </td>	<td>FNOTIFY *</td> "
			"<td> 0x0 </td>", szOffsetTable[3]);
	}
	printTableRowEnd();


	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>uiHighTransID</td>\n"
				"<td>FLMUINT</td>\n" TD_8x, szOffsetTable[4],
				LocalSCacheBlock.uiHighTransID);
	printTableRowEnd();

	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>uiUseCount</td>\n<td>FLMUINT</td>\n"
				 TD_lu,  szOffsetTable[5], LocalSCacheBlock.uiUseCount);
	printTableRowEnd();

	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>ui16Flags</td>\n<td>FLMUINT16</td>\n"
					"<td>0x%04X %s</td>\n", szOffsetTable[6],
					LocalSCacheBlock.ui16Flags, pszFlagNames);
	printTableRowEnd();

	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>ui16BlkSize</td>\n<td>FLMUINT16</td>\n" TD_i,
					szOffsetTable[7], LocalSCacheBlock.ui16BlkSize);
	printTableRowEnd();

#ifdef FLM_DEBUG
	printTableRowStart( bHighlight = ~bHighlight);
	fnPrintf( m_pHRequest, TD_s "<td>uiChecksum</td>\n"
					"<td>FLMUINT</td>\n" TD_8x,
					szOffsetTable[8], LocalSCacheBlock.uiChecksum);
	printTableRowEnd();
#endif


#ifdef FLM_DEBUG
		//Last line - the use list...
		printTableRowStart( bHighlight = ~bHighlight);
		if (LocalSCacheBlock.pUseList)
		{
			fnPrintf( m_pHRequest,
				TD_s " <td> <A href=\"javascript:openPopup('%s')> pUseList </A> </td>	<td> SCACHE_USE_p </td>		<td> <A href=\"javascript:openPopup('%s')> %s </A></td>",
				szOffsetTable[9], pszSCacheUseListRequest, pszSCacheUseListRequest, szAddressTable[3]);
		}
		else
		{
			fnPrintf( m_pHRequest,
				TD_s " <td> pUseList </td>	<td> SCACHE_USE_p </td>	<td> 0x0 </td>",
				szOffsetTable[9]);
		}
		printTableRowEnd();

#endif

	fnPrintf( m_pHRequest, TABLE_END "</BODY></HTML>\n");
	fnEmit();

Exit:

	// Even though uiLoop2 is not in the same scope as uiLoop, VC6 still
	// complains if this is called uiLoop....
	for (FLMUINT uiLoop2 = 0; uiLoop2 < 8; uiLoop2++)
	{
		if (pszSCacheRequestString[uiLoop2])
		{
			f_free( &pszSCacheRequestString[uiLoop2]);
		}
	}

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

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

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

	if (pszSCacheNotifyListRequest)
	{
		f_free( &pszSCacheNotifyListRequest);
	}
	
	if( pszFFileRequest)
	{
		f_free( &pszFFileRequest);
	}

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

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

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

	return( rc);
}
Пример #29
0
/****************************************************************************
Desc:	Prints the web page showing the binary data in an SCache block
****************************************************************************/
RCODE F_SCacheDataPage::display( 
	FLMUINT			uiNumParams,
	const char ** 	ppszParams)
{
	RCODE			rc = FERR_OK;

	FLMUINT		uiBlkAddress = 0;
	FLMUINT		uiLowTransID = 0;
	FLMUINT		uiHighTransID = 0;
	FFILE *		pFile = NULL;
	FLMBOOL		bFlaimLocked = FALSE;
	SCACHE		LocalSCacheBlock;
	char *		pucData = NULL;
	char *		pucDataLine;
	char			szData[97];
	char			szOneChar[7];
	FLMUINT		uiCurrentOffset = 0;
	FLMUINT		uiLoop = 0;
	
	f_mutexLock( gv_FlmSysData.hShareMutex);
	bFlaimLocked = TRUE;
	rc = locateSCacheBlock( uiNumParams, ppszParams, &LocalSCacheBlock,
									&uiBlkAddress, &uiLowTransID,	&uiHighTransID,
									&pFile);
	if (RC_BAD( rc))
	{
		if(rc == FERR_NOT_FOUND)
		{
			notFoundErr();
			rc = FERR_OK;
		}
		goto Exit;
	}
	else
	{
		// Store the data in a local variable...
		if( RC_BAD( rc = f_alloc( 
			LocalSCacheBlock.ui16BlkSize, &pucData)))
		{
			goto Exit;
		}

		f_memcpy( pucData, LocalSCacheBlock.pucBlk, LocalSCacheBlock.ui16BlkSize);
	}

	f_mutexUnlock( gv_FlmSysData.hShareMutex);
	bFlaimLocked = FALSE;

	// Start the HTML...
	
	stdHdr();
	fnPrintf( m_pHRequest, HTML_DOCTYPE 
				"<HTML> <BODY>\n<font face=arial><PRE>\n");

	while (uiCurrentOffset < LocalSCacheBlock.ui16BlkSize)
	{
		szData[0] = '\0';
		pucDataLine =  pucData + uiCurrentOffset;
		fnPrintf( m_pHRequest, "<font color=blue>0x%04X</font>    "
						"%02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X    ",
						uiCurrentOffset,
						pucDataLine[ 0], pucDataLine[ 1], pucDataLine[ 2], pucDataLine[ 3],
						pucDataLine[ 4], pucDataLine[ 5], pucDataLine[ 6], pucDataLine[ 7],
						pucDataLine[ 8], pucDataLine[ 9], pucDataLine[10], pucDataLine[11],
						pucDataLine[12], pucDataLine[13], pucDataLine[14], pucDataLine[15]);
	
		for (uiLoop = 0; uiLoop < 16; uiLoop++)
		{
			if (	(pucDataLine[uiLoop] >= 32) &&  // 32 is a space
					(pucDataLine[uiLoop] <= 126)  ) // 126 is a ~
			{
				f_sprintf( szOneChar, "&#%d;", pucDataLine[uiLoop]);
			}
			else
			{
				f_strcpy( szOneChar, "&#46;"); // 46 is a .
			}
			f_strcat(szData, szOneChar);

			// The reason for all the &#xxx; nonsence is because if we just put
			// the characters into a string, when the brower comes across a <
			// character, it will try to interpret what follows as an HTML
			// tag...
		}

		fnPrintf( m_pHRequest, "<font color=green>%s</font>\n", szData);
		
		uiCurrentOffset += 16;
	}

	fnPrintf( m_pHRequest, "</PRE></font>\n</BODY> </HTML>\n");
	fnEmit();

Exit:
	if (bFlaimLocked)
	{
		f_mutexUnlock( gv_FlmSysData.hShareMutex);
	}

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

	return( rc);
}
Пример #30
0
/****************************************************************************
Desc:	Prints the web page for an SCACHEMGR struct
		(The URL for this page requires no parameters since there is only
		one SCACHE_MGR per copy of FLAIM.)
****************************************************************************/
RCODE F_SCacheMgrPage::display(
	FLMUINT			uiNumParams,
	const char ** 	ppszParams)
{
	RCODE			rc = FERR_OK;
	SCACHE_MGR	LocalSCacheMgr;
	FLMBOOL		bAutoRefresh;
#define NUM_CACHE_REQ_STRINGS			4
	char	*		pszSCacheRequestString[ NUM_CACHE_REQ_STRINGS];
	char			szOffsetTable[12][6];
	char			szAddressTable[2][20];
	FLMBOOL		bHighlight = FALSE;
	char *		pszTemp = NULL;
	FLMUINT		uiLoop;

	// Note: The SCacheBlock requests need the following params:
	// "BlockAddress", "File", "LowTransID" and "HighTransID"
	// ex:  <A href="SCacheBlock?BlockAddress=100?File=5?LowTransID=30?HighTransID=100"> pMRUCache </A>
	
	if( RC_BAD( rc = f_alloc( 200, &pszTemp)))
	{
		printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
		goto Exit;
	}

	// First thing that we need to do is grab a local copy of gv_FlmSysData.SCacheMgr,
	// and of the data for the three SCache blocks that it has pointers to...
	for (uiLoop = 0; uiLoop < NUM_CACHE_REQ_STRINGS; uiLoop++)
	{
		if( RC_BAD( rc = f_alloc( 150,
									&pszSCacheRequestString[ uiLoop])))
		{
			printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
			goto Exit;
		}
	}
	f_mutexLock( gv_FlmSysData.hShareMutex);
	f_memcpy (&LocalSCacheMgr, &gv_FlmSysData.SCacheMgr, sizeof (LocalSCacheMgr));
	flmBuildSCacheBlockString( pszSCacheRequestString[0], LocalSCacheMgr.pMRUCache);
	flmBuildSCacheBlockString( pszSCacheRequestString[1], LocalSCacheMgr.pLRUCache);
	flmBuildSCacheBlockString( pszSCacheRequestString[2], LocalSCacheMgr.pFirstFree);
	flmBuildSCacheBlockString( pszSCacheRequestString[3], LocalSCacheMgr.pLastFree);
	f_mutexUnlock( gv_FlmSysData.hShareMutex);

	bAutoRefresh = DetectParameter( uiNumParams, ppszParams, "Refresh");

	// Now - are we being asked to display the usage stats?  Or is this a regular page...
	if (DetectParameter( uiNumParams, ppszParams, "Usage"))
	{
		// There's a function to handle display the usage info (because both
		// RCacheMgr and SCacheMgr have usage stats).
		writeUsage( &LocalSCacheMgr.Usage, bAutoRefresh,
						"/SCacheMgr?Usage",
						"Usage Statistics for the SCache");
	}
	else // This is a regular SCacheMgr page...
	{
		// Determine if we are being requested to refresh this page or  not.

		stdHdr();

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

		if (bAutoRefresh)
		{
			// Send back the page with a refresh command in the header

			fnPrintf( m_pHRequest, 
				"<HEAD>"
				"<META http-equiv=\"refresh\" content=\"5; url=%s/SCacheMgr?Refresh\">"
				"<TITLE>gv_FlmSysData.SCacheMgr</TITLE>\n", m_pszURLString);

			printStyle();
			popupFrame();  //Spits out a Javascript function that will open a new window..
	
			fnPrintf( m_pHRequest, "\n</HEAD>\n<body>\n");


			f_sprintf( (char *)pszTemp,
							"<A HREF=%s/SCacheMgr>Stop Auto-refresh</A>", m_pszURLString);
		}
		else  // bAutoRefresh == FALSE
		{
			// Send back a page without the refresh command
			fnPrintf( m_pHRequest, 
				"<HEAD>"
				"<TITLE>gv_FlmSysData.SCacheMgr</TITLE>\n");

			printStyle();
			popupFrame();  //Spits out a Javascript function that will open a new window..
	
			fnPrintf( m_pHRequest, "\n</HEAD>\n<body>\n");

			f_sprintf( (char *)pszTemp,
						"<A HREF=%s/SCacheMgr?Refresh>Start Auto-refresh (5 sec.)</A>",
						m_pszURLString);
		}

		// Write out the table headings
		printTableStart( "SCache Manager Structure", 4);

		printTableRowStart();
		printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
		fnPrintf( m_pHRequest, "<A HREF=%s/SCacheMgr>Refresh</A>, %s\n", m_pszURLString, pszTemp);
		printColumnHeadingClose();
		printTableRowEnd();

		// Write out the table headings.
		printTableRowStart();
		printColumnHeading( "Byte Offset (hex)");
		printColumnHeading( "Field Name");
		printColumnHeading( "Field Type");
		printColumnHeading( "Value");
		printTableRowEnd();
	
		//Now - we have three rows in the table that may or may not have hyperlinks in them.  
		printTableRowStart( bHighlight = ~bHighlight);
		flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[0], "pMRUCache", &LocalSCacheMgr, &LocalSCacheMgr.pMRUCache);
		printTableRowStart( bHighlight = ~bHighlight);
		flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[1], "pLRUCache", &LocalSCacheMgr, &LocalSCacheMgr.pLRUCache);
		printTableRowStart( bHighlight = ~bHighlight);
		flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[2], "pFirstFree", &LocalSCacheMgr, &LocalSCacheMgr.pFirstFree);
		printTableRowStart( bHighlight = ~bHighlight);
		flmPrintCacheLine(m_pHRequest, pszSCacheRequestString[3], "pLastFree", &LocalSCacheMgr, &LocalSCacheMgr.pLastFree);

		//Format the strings that are displayed in the Offset column on of the table
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.ppHashTbl, szOffsetTable[0]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.Usage, szOffsetTable[1]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.bAutoCalcMaxDirty, szOffsetTable[2]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiMaxDirtyCache, szOffsetTable[3]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiLowDirtyCache, szOffsetTable[4]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiTotalUses, szOffsetTable[5]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiBlocksUsed, szOffsetTable[6]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiPendingReads, szOffsetTable[7]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiIoWaits, szOffsetTable[8]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiHashTblSize, szOffsetTable[9]);
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.uiHashTblBits, szOffsetTable[10]);
#ifdef FLM_DEBUG
		printOffset(&LocalSCacheMgr, &LocalSCacheMgr.bDebug, szOffsetTable[11]);
#endif


		printAddress( LocalSCacheMgr.ppHashTbl, szAddressTable[0]);
		printAddress( &LocalSCacheMgr.Usage, szAddressTable[1]);

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s
				"<td><A HREF=\"%s/SCacheHashTable?Start=0\">ppHashTbl</A></td>\n"
				"<td>SCACHE **</td>\n"
				"<td><A href=\"%s/SCacheHashTbl\">%s</A></td>\n",
				szOffsetTable[0], m_pszURLString, m_pszURLString, szAddressTable[0]);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s
			"<td><A href=\"javascript:openPopup('%s/SCacheMgr?Usage')\">Usage</A></td>\n"
			"<td>FLM_CACHE_USAGE</td>\n"
			"<td><A href=\"javascript:openPopup('%s/SCacheMgr?Usage')\">%s</A></td>\n",
			szOffsetTable[1], m_pszURLString, m_pszURLString, szAddressTable[1]);
		printTableRowEnd();

		// uiFreeCount
		printHTMLUint(
			(char *)"uiFreeCount",
			(char *)"FLMUINT",
			(void *)&LocalSCacheMgr,
			(void *)&LocalSCacheMgr.uiFreeCount,
			LocalSCacheMgr.uiFreeCount,
			(bHighlight = ~bHighlight));

		// uiFreeBytes
		printHTMLUint(
			(char *)"uiFreeBytes",
			(char *)"FLMUINT",
			(void *)&LocalSCacheMgr,
			(void *)&LocalSCacheMgr.uiFreeBytes,
			LocalSCacheMgr.uiFreeBytes,
			(bHighlight = ~bHighlight));

		// uiReplaceableCount
		printHTMLUint(
			(char *)"uiReplaceableCount",
			(char *)"FLMUINT",
			(void *)&LocalSCacheMgr,
			(void *)&LocalSCacheMgr.uiReplaceableCount,
			LocalSCacheMgr.uiReplaceableCount,
			(bHighlight = ~bHighlight));

		// uiReplaceableBytes
		printHTMLUint(
			(char *)"uiReplaceableBytes",
			(char *)"FLMUINT",
			(void *)&LocalSCacheMgr,
			(void *)&LocalSCacheMgr.uiReplaceableBytes,
			LocalSCacheMgr.uiReplaceableBytes,
			(bHighlight = ~bHighlight));

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>bAutoCalcMaxDirty</td>\n"
						"<td>FLMBOOL</td>\n" TD_i, szOffsetTable[2],
						LocalSCacheMgr.bAutoCalcMaxDirty);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiMaxDirtyCache</td>\n"
						"<td>FLMUINT</td>\n" TD_lu, szOffsetTable[3],
						LocalSCacheMgr.uiMaxDirtyCache);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiLowDirtyCache</td>\n"
						"<td>FLMUINT</td>\n" TD_lu, szOffsetTable[4],
						LocalSCacheMgr.uiLowDirtyCache);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiTotalUses</td>\n"
						"<td>FLMUINT</td>\n" TD_lu, szOffsetTable[5],
						LocalSCacheMgr.uiTotalUses);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiBlocksUsed</td> <td>FLMUINT</td>\n"
					TD_lu, szOffsetTable[6], LocalSCacheMgr.uiBlocksUsed);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiPendingReads</td>\n"
			"<td>FLMUINT</td>\n" TD_lu,  szOffsetTable[7],
			LocalSCacheMgr.uiPendingReads);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiIoWaits</td>\n <td>FLMUINT</td>\n" TD_lu,
						szOffsetTable[8], LocalSCacheMgr.uiIoWaits);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiHashTableSize</td>\n"
					"<td>FLMUINT</td>\n" TD_lu, szOffsetTable[9],
					LocalSCacheMgr.uiHashTblSize);
		printTableRowEnd();

		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>uiHashTableBits</td>\n"
					"<td>FLMUINT</td>\n" TD_lu, szOffsetTable[10],
					LocalSCacheMgr.uiHashTblBits);
		printTableRowEnd();

#ifdef FLM_DEBUG
		printTableRowStart( bHighlight = ~bHighlight);
		fnPrintf( m_pHRequest, TD_s "<td>bDebug</td>\n" "<td>FLMBOOL</td>\n"
					TD_i, szOffsetTable[11], LocalSCacheMgr.bDebug);
		printTableRowEnd();
#endif

		printTableEnd();
		
		fnPrintf( m_pHRequest, "</BODY></HTML>\n");

		fnEmit();

	}

Exit:

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

	for (uiLoop = 0; uiLoop < NUM_CACHE_REQ_STRINGS; uiLoop++)
	{
		if( pszSCacheRequestString[uiLoop])
		{
			f_free( &pszSCacheRequestString[uiLoop]);
		}
	}

	return( rc);
}