/**************************************************************************** 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; }
/**************************************************************************** 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; }
/**************************************************************************** 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); }
/**************************************************************************** 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; }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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; }
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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/****************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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)); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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; }
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; }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/*************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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); }
/**************************************************************************** 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 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); }
/**************************************************************************** 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); }