Files
mars-flaim/flaim/src/imonsche.cpp

1367 lines
42 KiB
C++

//-------------------------------------------------------------------------
// Desc: Class for displaying an SCACHE structure in HTML on a web page.
// Tabs: 3
//
// Copyright (c) 2001-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: imonsche.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
FSTATIC void flmPrintCacheLine(
HRequest * pHRequest,
const char * pszHREF,
const char * pszName,
void * pBaseAddr,
SCACHE ** ppSCache);
FSTATIC void flmBuildSCacheBlockString(
char * pszString,
SCACHE * pScache);
/****************************************************************************
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 for an SCACHE use list
This function is essentially unimplemented because I have yet to see
an SCache page where the use_list value was non-null!!
****************************************************************************/
RCODE F_SCacheUseListPage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
F_UNREFERENCED_PARM( uiNumParams);
F_UNREFERENCED_PARM( ppszParams);
RCODE rc = FERR_OK;
stdHdr();
fnPrintf( m_pHRequest,
HTML_DOCTYPE "\n<html>\n <body>\n"
"Congratulations! You've managed to find an SCache block with a valid "
"use list! Too bad we haven't implemented a page to dislay use "
"lists yet...\n </body> </html>");
fnEmit();
return( rc);
}
/****************************************************************************
Desc: Prints the web page for an SCACHE notify list
This function is essentially unimplemented because I have yet to see
an SCache page where the notify list value was non-null!!
****************************************************************************/
RCODE F_SCacheNotifyListPage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
F_UNREFERENCED_PARM( uiNumParams);
F_UNREFERENCED_PARM( ppszParams);
RCODE rc = FERR_OK;
stdHdr();
fnPrintf( m_pHRequest,
HTML_DOCTYPE "\n<html>\n <body>\n"
"Congratulations! You've managed to find an SCache block with a valid "
"notify list! Too bad we haven't implemented a page to dislay use "
"lists yet...\n </body> </html>");
fnEmit();
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;"); // 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);
}
/****************************************************************************
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: Searches the SCache for the block referenced by the parameters. If
found, it copies the data into pLocalSCache. Assumes that the
mutex has already been locked!
****************************************************************************/
RCODE F_SCacheBase::locateSCacheBlock(
FLMUINT uiNumParams,
const char ** ppszParams,
SCACHE * pLocalSCache,
FLMUINT * puiBlkAddress,
FLMUINT * puiLowTransID,
FLMUINT * puiHighTransID,
FFILE * * ppFile)
{
RCODE rc = FERR_OK;
FLMUINT uiSigBitsInBlkSize;
SCACHE * pSCache;
SCACHE ** ppSCache;
#define MAXPARAMLEN 15
char szBlkAddress[MAXPARAMLEN];
char szLowTransID[MAXPARAMLEN];
char szHighTransID[MAXPARAMLEN];
char szFile[MAXPARAMLEN];
// Grab the block address, low and high trans id's and FFile pointer, which
// we need to uniquely identify an scache block...
if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
"BlockAddress", sizeof( szBlkAddress),
&szBlkAddress[0])))
{
goto Exit;
}
*puiBlkAddress = f_atoi( szBlkAddress);
if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
"LowTransID", sizeof( szLowTransID),
&szLowTransID[0])))
{
goto Exit;
}
*puiLowTransID = f_atoi( szLowTransID);
if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
"HighTransID", sizeof( szHighTransID),
&szHighTransID[0])))
{
goto Exit;
}
*puiHighTransID = f_atoi( szHighTransID);
if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
"File", sizeof( szFile),
&szFile[0])))
{
goto Exit;
}
*ppFile = (FFILE *)f_atoud( szFile);
flmAssert( *ppFile);
uiSigBitsInBlkSize = (*ppFile)->FileHdr.uiSigBitsInBlkSize;
// ScaHash actually returns a pointer to the first scache in the hash
// bucket. It's up to us to traverse this list to find the proper block
// address and FFile (and potentially high and low trans id)
ppSCache = ScaHash( uiSigBitsInBlkSize, *puiBlkAddress);
pSCache = *ppSCache;
while ( pSCache &&
( (pSCache->uiBlkAddress != *puiBlkAddress) ||
(pSCache->pFile != *ppFile) ) )
{
pSCache = pSCache->pNextInHashBucket;
}
// Ok - we've found the right address and ffile. Do we need a different
// version?
while ( (pSCache) &&
(pSCache->uiHighTransID != *puiHighTransID) &&
(scaGetLowTransID( pSCache) != *puiLowTransID) )
{
pSCache = pSCache->pNextInVersionList;
}
// Now, if we've found the right block, copy it's contents to local memory...
if (pSCache)
{
f_memcpy( pLocalSCache, pSCache, sizeof( SCACHE));
}
else
{
rc = RC_SET( FERR_NOT_FOUND);
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Spits out a short message saying that the SCache block you were
looking for wasn't found. Used when locateSCacheBlock()
returns FERR_NOT_FOUND.
****************************************************************************/
void F_SCacheBase::notFoundErr()
{
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE "<html>\n<HEAD>\n");
printStyle();
fnPrintf( m_pHRequest,
"</HEAD><BODY>\n"
"<H2 ALIGN=CENTER>SCache Block Not Found</H2>"
"<HR><P> Unable to find the SCache Block that you requested."
" This is probably because the state of the cache changed between the time"
" that you displayed the previous page and the time that you clicked on the"
" link that brought you here. (It's also possible that the link you selected"
" was a NULL pointer.) \n"
" <P>Your best bet is probably to click on the \"Database System Data\" link on"
" the left.</P>\n</BODY></HTML>\n");
fnEmit();
}
/****************************************************************************
Desc: Spits out a short message saying that the URL for the SCache
block that was requested was badly formed. Used when
locateSCacheBlock() returns FERR_MEM.
****************************************************************************/
void F_SCacheBase::malformedUrlErr()
{
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE "<html>\n<HEAD>\n");
printStyle();
fnPrintf( m_pHRequest,
"</HEAD><BODY>\n"
"<H2 ALIGN=CENTER>Bad SCache Block URL</H2>"
"<HR><P> Couldn't process requested URL. Is"
" the query string properly formed?.</P>\n</BODY></HTML>\n");
fnEmit();
}
/****************************************************************************
Desc: Generates the html to display a row in a table. If *ppSCache is
a valid pointer, then that line will have hyperlinks in it.
****************************************************************************/
FSTATIC void flmPrintCacheLine(
HRequest * pHRequest,
const char * pszHREF,
const char * pszName,
void * pBaseAddr,
SCACHE ** ppSCache)
{
char szAddress[20];
char szOffset[8];
PRINTF_FN fnPrintf = gv_FlmSysData.HttpConfigParms.fnPrintf;
printAddress( *ppSCache, szAddress);
printOffset( pBaseAddr, ppSCache, szOffset);
if ((*ppSCache) && (*ppSCache)->pFile && pszHREF)
{
// We have a pointer to a valid SCache block and a valid HREF string,
// so we need hyperlinks to appear in the browser...
fnPrintf( pHRequest, TD_s TD_a_s_s " </td> <td> SCACHE * </td> " TD_a_s_s TR_END,
szOffset, pszHREF, pszName, pszHREF, szAddress);
}
else
{
fnPrintf( pHRequest, TD_s TD_s " <td> SCACHE * </td> " TD_s TR_END,
szOffset, pszName, szAddress );
}
}
/****************************************************************************
Desc: Determines the values of the parameters needed to reference
a specific SCache block. Must be called from within a mutex
****************************************************************************/
FSTATIC void flmBuildSCacheBlockString(
char * pszString,
SCACHE * pSCache)
{
char szAddress[ 20];
if ((pSCache == NULL) || (pSCache->pFile == NULL))
{
pszString[0] = 0;
}
else
{
printAddress( pSCache->pFile, szAddress);
f_sprintf( (char *)pszString,
"%s/SCacheBlock?BlockAddress=%lu&File=%s&LowTransID=%lu&HighTransID=%lu",
gv_FlmSysData.HttpConfigParms.pszURLString, pSCache->uiBlkAddress, szAddress,
scaGetLowTransID( pSCache), pSCache->uiHighTransID);
}
return;
}