Files
mars-flaim/flaim/src/imonbase.cpp
ahodgkinson 7de8b6be39 Ported FLAIM to FTK.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@509 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-06-05 22:59:36 +00:00

2753 lines
74 KiB
C++

//-------------------------------------------------------------------------
// Desc: Base class for monitoring code.
// 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: imonbase.cpp 12334 2006-01-23 12:45:35 -0700 (Mon, 23 Jan 2006) dsanders $
//-------------------------------------------------------------------------
#include "flaimsys.h"
#define RESP_WRITE_BUF_SIZE 1024
#define FLM_SESSION_ID_NAME "flmsessionid"
#define MAX_FIELD_SIZE(uiSize) \
(uiSize > 100 ? 100 : (uiSize < 20 ? 20 : uiSize))
/****************************************************************************
Desc: Outputs a javascript function that, when called, causes a new
window to open and a page to be displayed in it.
****************************************************************************/
void F_WebPage::popupFrame( void)
{
fnPrintf( m_pHRequest, "<SCRIPT LANGUAGE=\"JavaScript\">\n");
fnPrintf( m_pHRequest, "var windowW=600\n"); // wide
fnPrintf( m_pHRequest, "var windowH=500\n"); // high
fnPrintf( m_pHRequest, "var windowX = 100\n"); // from left
fnPrintf( m_pHRequest, "var windowY = 100\n"); // from top
fnPrintf( m_pHRequest, "var title = \"Popup Window\"\n");
fnPrintf( m_pHRequest, "var autoclose = false\n");
fnPrintf( m_pHRequest, "function openPopup( urlPop) {\n");
fnPrintf( m_pHRequest, "if (openPopup.arguments.length == 5)\n");
fnPrintf( m_pHRequest, "{\nwindowW = openPopup.arguments[1];\n");
fnPrintf( m_pHRequest, "windowH = openPopup.arguments[2];\n");
fnPrintf( m_pHRequest, "windowX = openPopup.arguments[3];\n");
fnPrintf( m_pHRequest, "windowY = openPopup.arguments[4];\n}\n");
fnPrintf( m_pHRequest, "s = \"width=\"+windowW+\",height=\"+windowH;\n");
fnPrintf( m_pHRequest,
"NFW = window.open(urlPop,\"popFrameless\",\"scrollbars,resizable,\"+s);\n");
fnPrintf( m_pHRequest, "NFW.blur();\n");
fnPrintf( m_pHRequest, "window.focus();\n");
fnPrintf( m_pHRequest, "NFW.resizeTo(windowW,windowH);\n");
fnPrintf( m_pHRequest, "NFW.moveTo(windowX,windowY);\n");
fnPrintf( m_pHRequest, "NFW.focus();\n");
fnPrintf( m_pHRequest, "}\n</script>\n");
}
/******************************************************************************
Desc: This method will extract the value of the parameter in the form of
PARAMETER=VALUE
*******************************************************************************/
RCODE F_WebPage::ExtractParameter(
FLMUINT uiNumParams,
const char ** ppszParams,
const char * pszParamName,
FLMUINT uiParamLen,
char* pszParamValue)
{
RCODE rc = FERR_OK;
FLMUINT uiLoop;
FLMUINT uiParamNameLen;
const char* pszTemp;
FLMBOOL bFound = FALSE;
uiParamNameLen = f_strlen( pszParamName);
for (uiLoop = 0; uiLoop < uiNumParams; uiLoop++)
{
if( f_strncmp( (char*) ppszParams[uiLoop], pszParamName, uiParamNameLen) == 0 &&
(ppszParams[uiLoop][uiParamNameLen] == '\0' ||
ppszParams[uiLoop][uiParamNameLen] == '='))
{
pszTemp = &ppszParams[uiLoop][uiParamNameLen];
if (*pszTemp == '=')
{
// Skip past the equal sign
pszTemp++;
f_strncpy( pszParamValue, pszTemp, uiParamLen - 1);
// See if the param was too long to store
if (f_strlen( pszTemp) >= uiParamLen)
{
pszParamValue[uiParamLen] = '\0';
rc = RC_SET( FERR_MEM);
}
}
else
{
*pszParamValue = 0;
}
bFound = TRUE;
break;
}
}
return (bFound ? rc : RC_SET( FERR_NOT_FOUND));
}
/****************************************************************************
Desc: This method will detect the presence of a parameter in the form
PARAMETER - no value will be checked. A TRUE or FALSE value will
be returned.
*****************************************************************************/
FLMBOOL F_WebPage::DetectParameter(
FLMUINT uiNumParams,
const char ** ppszParams,
const char * pszParamName)
{
for (FLMUINT uiLoop = 0; uiLoop < uiNumParams; uiLoop++)
{
if (f_strncmp( (char*) ppszParams[uiLoop], pszParamName,
f_strlen( (char*) pszParamName)) == 0)
{
return (TRUE);
}
}
return (FALSE);
}
/****************************************************************************
Desc:
*****************************************************************************/
RCODE F_WebPage::getDatabaseHandleParam(
FLMUINT uiNumParams,
const char ** ppszParams,
F_Session * pFlmSession,
HFDB* phDb,
char* pszKey)
{
RCODE rc = FERR_OK;
HFDB hDb;
char szTmp[ 64];
char * pTmp;
if (phDb)
{
*phDb = hDb = HFDB_NULL;
}
if (pszKey)
{
*pszKey = 0;
}
// Need to memset the first F_SESSION_DB_KEY_LEN bytes of szTmp
// because the hash lookup algorithm expects the buffer to be padded
// with zeros at the end of the key.
f_memset( szTmp, 0, F_SESSION_DB_KEY_LEN);
if (RC_BAD( ExtractParameter( uiNumParams, ppszParams, "dbhandle",
sizeof(szTmp), szTmp)))
{
pTmp = &szTmp[0];
if (RC_BAD( getFormValueByName( "dbhandle", &pTmp, sizeof(szTmp), NULL)))
{
rc = RC_SET( FERR_NOT_FOUND);
goto Exit;
}
}
if (szTmp[0])
{
if (RC_BAD( rc = pFlmSession->getDbHandle( szTmp, &hDb)))
{
goto Exit;
}
if (pszKey)
{
f_memcpy( pszKey, szTmp, F_SESSION_DB_KEY_LEN);
}
}
if (phDb)
{
*phDb = hDb;
}
Exit:
return (rc);
}
/****************************************************************************
Desc: Function to display the formatted time value in the form dd hh:mm:ss.ccc
*****************************************************************************/
void F_WebPage::FormatTime(
FLMUINT uiTimerUnits,
char * pszFormattedTime)
{
FLMUINT uiMilli;
FLMUINT uiSec;
FLMUINT uiMin;
FLMUINT uiHr;
FLMUINT uiDays;
FLMUINT uiTemp;
// Initialize to NULL;
pszFormattedTime[0] = '\0';
// Convert the timer units to milliseconds
uiMilli = FLM_TIMER_UNITS_TO_MILLI( uiTimerUnits);
// Determine the number of days
uiDays = uiMilli / 86400000;
uiTemp = uiMilli % 86400000;
// Now the hours
uiHr = uiTemp / 3600000;
uiTemp = uiTemp % 3600000;
// Determine the minutes
uiMin = uiTemp / 60000;
uiTemp = uiTemp % 60000;
// Determine seconds
uiSec = uiTemp / 1000;
// Determine the milliseconds
uiMilli = uiTemp % 1000;
// Put it all together - hh:mm:ss
f_sprintf( (char *) pszFormattedTime, "%ld %2.2ld:%2.2ld:%2.2ld.%3.3ld",
uiDays, uiHr, uiMin, uiSec, uiMilli);
}
/****************************************************************************
Desc: Procedure to generate the HTML page that displays the usage statistics
structure.
****************************************************************************/
RCODE F_WebPage::writeUsage(
FLM_CACHE_USAGE* pUsage,
FLMBOOL bRefresh,
const char* pszURL,
const char* pszTitle)
{
RCODE rc = FERR_OK;
FLMBOOL bHighlight = FALSE;
char szTemp[100];
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE);
fnPrintf( m_pHRequest, "<html>\n");
// Setup the page header & refresh control... Assuming the the first
// parameter ?Usage is already contained in the pszURL string.
if (bRefresh)
{
fnPrintf( m_pHRequest, "<HEAD>"
"<META http-equiv=\"refresh\" content=\"5; url=%s%s&Refresh\">"
"<TITLE>%s</TITLE>\n", m_pszURLString, pszURL, pszTitle);
printStyle();
fnPrintf( m_pHRequest, "</HEAD>\n<body>\n");
f_sprintf( (char*) szTemp, "<A HREF=%s%s>Stop Auto-refresh</A>",
m_pszURLString, pszURL);
}
else
{
fnPrintf( m_pHRequest, "<HEAD><TITLE>%s</TITLE>\n", pszTitle);
printStyle();
fnPrintf( m_pHRequest, "</HEAD>\n<body>\n");
f_sprintf( (char*) szTemp,
"<A HREF=%s%s&Refresh>Start Auto-refresh (5 sec.)</A>",
m_pszURLString, pszURL);
}
// Begin the table
printTableStart( (char*) pszTitle, 4);
printTableRowStart();
printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
fnPrintf( m_pHRequest, "<A HREF=%s%s>Refresh</A>, ", m_pszURLString, pszURL);
fnPrintf( m_pHRequest, "%s\n", szTemp);
printColumnHeadingClose();
printTableRowEnd();
// Write out the table headings.
printTableRowStart();
printColumnHeading( "Byte Offset (hex)");
printColumnHeading( "Field Name");
printColumnHeading( "Byte Offset");
printColumnHeading( "Value");
printTableRowEnd();
// uiMaxBytes
printHTMLUint( (char*) "uiMaxBytes", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiMaxBytes, pUsage->uiMaxBytes,
(bHighlight = ~bHighlight));
// uiTotalBytesAllocated
printHTMLUint( (char*) "uiTotalBytesAllocated", (char*) "FLMUINT",
(void*) pUsage, (void*) &pUsage->uiTotalBytesAllocated,
pUsage->uiTotalBytesAllocated, (bHighlight = ~bHighlight));
// uiCount
printHTMLUint( (char*) "uiCount", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiCount, pUsage->uiCount,
(bHighlight = ~bHighlight));
// uiOldVerCount
printHTMLUint( (char*) "uiOldVerCount", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiOldVerCount, pUsage->uiOldVerCount,
(bHighlight = ~bHighlight));
// uiOldVerBytes
printHTMLUint( (char*) "uiOldVerBytes", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiOldVerBytes, pUsage->uiOldVerBytes,
(bHighlight = ~bHighlight));
// uiCacheHits
printHTMLUint( (char*) "uiCacheHits", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiCacheHits, pUsage->uiCacheHits,
(bHighlight = ~bHighlight));
// uiCacheHitLooks
printHTMLUint( (char*) "uiCacheHitLooks", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiCacheHitLooks, pUsage->uiCacheHitLooks,
(bHighlight = ~bHighlight));
// uiCacheFaults
printHTMLUint( (char*) "uiCacheFaults", (char*) "FLMUINT", (void*) pUsage,
(void*) &pUsage->uiCacheFaults, pUsage->uiCacheFaults,
(bHighlight = ~bHighlight));
// uiCacheFaultLooks
printHTMLUint( (char*) "uiCacheFaultLooks", (char*) "FLMUINT",
(void*) pUsage, (void*) &pUsage->uiCacheFaultLooks,
pUsage->uiCacheFaultLooks, (bHighlight = ~bHighlight));
printTableEnd();
fnPrintf( m_pHRequest, "<form>\n");
fnPrintf( m_pHRequest,
"<center><input type=\"button\" value=\"Close\" onClick=\"window.close()\"></center>\n");
fnPrintf( m_pHRequest, "</form>\n");
fnPrintf( m_pHRequest, "</body></html>\n");
fnEmit();
return (rc);
}
/*********************************************************************
Desc: This function prints a linkable field in HTML
*********************************************************************/
void F_WebPage::printHTMLLink(
const char * pszName,
const char * pszType,
void * pvBase,
void * pvAddress,
void * pvValue,
const char * pszLink,
FLMBOOL bHighlight)
{
char szAddress[20];
char szOffset[8];
printOffset( pvBase, pvAddress, szOffset);
printTableRowStart( bHighlight);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
if (pvValue)
{
printAddress( pvValue, szAddress);
fnPrintf( m_pHRequest, TD_a_s_s, pszLink, pszName); // Link & Name
fnPrintf( m_pHRequest, TD_s, pszType); // Type
fnPrintf( m_pHRequest, TD_a_s_s, pszLink, szAddress); // Link & Value
}
else
{
fnPrintf( m_pHRequest, TD_s, pszName);
fnPrintf( m_pHRequest, TD_s, pszType);
fnPrintf( m_pHRequest, TD_s, "Null");
}
printTableRowEnd();
}
/*********************************************************************
Desc: This function prints a text field in HTML
*********************************************************************/
void F_WebPage::printHTMLString(
const char * pszName,
const char * pszType,
void * pvBase,
void * pvAddress,
const char * pszValue,
FLMBOOL bHighlight)
{
char szOffset[8];
printOffset( pvBase, pvAddress, szOffset);
printTableRowStart( bHighlight);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
fnPrintf( m_pHRequest, TD_s, pszName); // Name
fnPrintf( m_pHRequest, TD_s, pszType); // Type
fnPrintf( m_pHRequest, TD_s, pszValue); // Value
printTableRowEnd();
}
/*********************************************************************
Desc: This function prints a unsigned long (FLMUINT) field in HTML
*********************************************************************/
void F_WebPage::printHTMLUint(
const char * pszName,
const char * pszType,
void * pvBase,
void * pvAddress,
FLMUINT uiValue,
FLMBOOL bHighlight)
{
char szOffset[8];
printOffset( pvBase, pvAddress, szOffset);
printTableRowStart( bHighlight);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
fnPrintf( m_pHRequest, TD_s, pszName); // Name
fnPrintf( m_pHRequest, TD_s, pszType); // Type
fnPrintf( m_pHRequest, TD_ui, uiValue); // Value
printTableRowEnd();
}
/*********************************************************************
Desc: This function prints a signed long (FLMINT) field in HTML
*********************************************************************/
void F_WebPage::printHTMLInt(
const char * pszName,
const char * pszType,
void * pvBase,
void * pvAddress,
FLMINT iValue,
FLMBOOL bHighlight)
{
char szOffset[8];
printOffset( pvBase, pvAddress, szOffset);
printTableRowStart( bHighlight);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
fnPrintf( m_pHRequest, TD_s, pszName); // Name
fnPrintf( m_pHRequest, TD_s, pszType); // Type
fnPrintf( m_pHRequest, TD_i, iValue); // Value
printTableRowEnd();
}
/*********************************************************************
Desc: This function prints a unsigned long field in HTML
*********************************************************************/
void F_WebPage::printHTMLUlong(
const char * pszName,
const char * pszType,
void * pvBase,
void * pvAddress,
unsigned long luValue,
FLMBOOL bHighlight)
{
char szOffset[8];
printOffset( pvBase, pvAddress, szOffset);
printTableRowStart( bHighlight);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
fnPrintf( m_pHRequest, TD_s, pszName); // Name
fnPrintf( m_pHRequest, TD_s, pszType); // Type
fnPrintf( m_pHRequest, TD_lu, luValue); // Value
printTableRowEnd();
}
/*********************************************************************
Desc: This function takes the name of a form field, and returns a
pointer to it. This will allocate the buffer returned. The
calling function is responsible for freeing that buffer.
*********************************************************************/
RCODE F_WebPage::getFormValueByName(
const char * pszValueTag,
char ** ppszBuf,
FLMUINT uiBufLen,
FLMUINT * puiDataLen)
{
RCODE rc = FERR_OK;
char szTag[128];
char * pszValue;
FLMUINT uiLen;
FLMBOOL bFreeFormData = FALSE;
FLMBOOL bFreeUserData = FALSE;
if (puiDataLen)
{
*puiDataLen = 0;
}
#ifdef FLM_DEBUG
if (!uiBufLen)
{
flmAssert( ppszBuf && *ppszBuf == NULL);
}
#endif
if (f_strlen( pszValueTag) + 1 >= sizeof(szTag))
{
flmAssert( 0);
rc = RC_SET( FERR_MEM);
goto Exit;
}
f_sprintf( (char*) szTag, "%s=", pszValueTag);
if (!m_pszFormData)
{
char * pszContentLength;
FLMUINT uiContentLength;
// First we need to determine how much form data there is.
if ((pszContentLength = (char*) fnReqHdrValue( "Content-Length")) == NULL)
{
rc = RC_SET( FERR_NOT_FOUND);
goto Exit;
}
if ((uiContentLength = f_atoi( pszContentLength)) == 0)
{
rc = RC_SET( FERR_NOT_FOUND);
goto Exit;
}
// Now allocate a buffer to hold the form data
if (RC_BAD( rc = f_alloc( uiContentLength + 1, &m_pszFormData)))
{
goto Exit;
}
bFreeFormData = TRUE;
if (fnRecvBuffer( m_pszFormData, (FLMSIZET *) &uiContentLength) != 0)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
m_pszFormData[uiContentLength] = 0;
bFreeFormData = FALSE;
}
// Now, parse through the buffer until we find the field we are
// looking for. The data is in the form name=value:name=value...
if ((pszValue = f_strstr( m_pszFormData, szTag)) != NULL)
{
pszValue += f_strlen( szTag);
for (uiLen = 0;
pszValue[uiLen] && pszValue[uiLen] != ':' && pszValue[uiLen] != '&';
uiLen++);
if (ppszBuf)
{
if (!uiBufLen)
{
uiBufLen = uiLen + 1;
bFreeUserData = TRUE;
*ppszBuf = NULL;
if (RC_BAD( rc = f_alloc( uiBufLen, ppszBuf)))
{
goto Exit;
}
}
if (uiLen >= uiBufLen)
{
rc = RC_SET( FERR_CONV_DEST_OVERFLOW);
goto Exit;
}
f_memcpy( *ppszBuf, pszValue, uiLen);
(*ppszBuf)[uiLen] = 0;
bFreeUserData = FALSE;
}
if (puiDataLen)
{
*puiDataLen = uiLen + 1;
}
goto Exit;
}
else
{
rc = RC_SET( FERR_NOT_FOUND);
goto Exit;
}
Exit:
if (bFreeFormData)
{
f_free( &m_pszFormData);
}
if (bFreeUserData && *ppszBuf)
{
f_free( ppszBuf);
}
return (rc);
}
/****************************************************************************
Desc: Prints the standard style sheet
****************************************************************************/
void F_WebPage::printStyle(void)
{
fnPrintf( m_pHRequest,
"<link REL=stylesheet TYPE=text/css HREF=%s/staticfile/style.css>\n",
m_pszURLString);
}
/****************************************************************************
Desc: Outputs a column heading using elements from the standard style sheet
****************************************************************************/
void F_WebPage::printColumnHeading(
const char * pszHeading,
JustificationType eJustification,
const char * pszBackground,
FLMUINT uiColSpan,
FLMUINT uiRowSpan,
FLMBOOL bClose,
FLMUINT uiWidth)
{
fnPrintf( m_pHRequest,
"<td class=\"tablecolumnhead1\" colspan=%u rowspan=%u",
(unsigned) uiColSpan,
(unsigned) uiRowSpan);
if (uiWidth)
{
fnPrintf( m_pHRequest, " width=\"%u%%\"", (unsigned) uiWidth);
}
if (pszBackground)
{
fnPrintf( m_pHRequest, " bgColor=\"%s\"", pszBackground);
}
if (eJustification == JUSTIFY_CENTER)
{
fnPrintf( m_pHRequest, " align=\"center\"");
}
else if (eJustification == JUSTIFY_RIGHT)
{
fnPrintf( m_pHRequest, " align=\"right\"");
}
else
{
fnPrintf( m_pHRequest, " align=\"left\"");
}
fnPrintf( m_pHRequest, ">\n");
if (pszHeading)
{
printEncodedString( pszHeading);
}
if (bClose)
{
fnPrintf( m_pHRequest, "</td>\n");
}
}
/****************************************************************************
Desc: Closes a column heading
****************************************************************************/
void F_WebPage::printColumnHeadingClose(void)
{
fnPrintf( m_pHRequest, "</td>\n");
}
/****************************************************************************
Desc: Encodes a string for rendering in an HTML page or for inclusion in
an URL
****************************************************************************/
void F_WebPage::printEncodedString(
const char * pszString,
FStringEncodeType eEncodeType,
FLMBOOL bMapSlashes)
{
char ucChar;
while ((ucChar = *pszString) != 0)
{
if ((ucChar >= '0' && ucChar <= '9') ||
(ucChar >= 'A' && ucChar <= 'Z') ||
(ucChar >= 'a' && ucChar <= 'z') ||
ucChar == '_' ||
(
eEncodeType == URL_PATH_ENCODING &&
(ucChar == '.' || (bMapSlashes && (ucChar == '/' || ucChar == '\\')))
))
{
if (ucChar == '\\')
{
ucChar = '/';
}
fnPrintf( m_pHRequest, "%c", ucChar);
}
else if (eEncodeType == URL_PATH_ENCODING)
{
fnPrintf( m_pHRequest, "%%%02X", (unsigned) ucChar);
}
else if (eEncodeType == URL_QUERY_ENCODING)
{
if (ucChar == ' ')
{
ucChar = '+';
}
fnPrintf( m_pHRequest, "%%%02X", (unsigned) ucChar);
}
else // HTML encoding
{
fnPrintf( m_pHRequest, "&#%u;", (unsigned) ucChar);
}
pszString++;
}
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printDocStart(
const char * pszTitle,
FLMBOOL bPrintTitle,
FLMBOOL bStdHeader,
const char * pszBackground)
{
if (bStdHeader)
{
stdHdr();
}
fnPrintf( m_pHRequest, HTML_DOCTYPE);
fnPrintf( m_pHRequest, "<html>\n");
fnPrintf( m_pHRequest, "<head>\n");
printRecordStyle();
printStyle();
fnPrintf( m_pHRequest, "<title>Database iMonitor - ");
printEncodedString( pszTitle);
fnPrintf( m_pHRequest, "</title>\n");
fnPrintf( m_pHRequest, "</head>\n");
fnPrintf( m_pHRequest, "<body bgcolor=\"%s\">\n",
pszBackground ? pszBackground : "white");
if (bPrintTitle)
{
printTableStart( pszTitle, 1);
printTableEnd();
fnPrintf( m_pHRequest, "<BR>\n");
}
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printDocEnd(void)
{
fnPrintf( m_pHRequest, "</body>\n");
fnPrintf( m_pHRequest, "</html>\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printMenuReload(void)
{
fnPrintf( m_pHRequest, "<script>parent.Menu.location.reload( true)\n");
fnPrintf( m_pHRequest, "</script>\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableStart(
const char* pszTitle,
FLMUINT uiColumns,
FLMUINT uiWidthFactor)
{
fnPrintf( m_pHRequest, "<table border=0 cellpadding=2 cellspacing=0");
if (uiWidthFactor)
{
fnPrintf( m_pHRequest, " width=%u%%", (unsigned) uiWidthFactor);
}
fnPrintf( m_pHRequest, ">\n");
if (pszTitle)
{
printTableRowStart();
fnPrintf( m_pHRequest, "<td colspan=%u class=\"tablehead1\"",
(unsigned) uiColumns);
fnPrintf( m_pHRequest, ">\n");
printEncodedString( pszTitle);
fnPrintf( m_pHRequest, "</td>");
printTableRowEnd();
}
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableEnd(void)
{
fnPrintf( m_pHRequest, "</table>\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableRowStart(
FLMBOOL bHighlight)
{
fnPrintf( m_pHRequest, "<tr class=\"mediumtext\"");
if (bHighlight)
{
fnPrintf( m_pHRequest, " bgColor=\"%s\"", FLM_IMON_COLOR_PUTTY_2);
}
fnPrintf( m_pHRequest, ">\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableRowEnd(void)
{
fnPrintf( m_pHRequest, "</tr>\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableDataStart(
FLMBOOL bNoWrap,
JustificationType eJustification,
FLMUINT uiWidth)
{
fnPrintf( m_pHRequest, "<td");
if (uiWidth)
{
fnPrintf( m_pHRequest, " width=%u%%", (unsigned) uiWidth);
}
if (bNoWrap)
{
fnPrintf( m_pHRequest, " nowrap");
}
if (eJustification == JUSTIFY_CENTER)
{
fnPrintf( m_pHRequest, " align=\"center\"");
}
else if (eJustification == JUSTIFY_RIGHT)
{
fnPrintf( m_pHRequest, " align=\"right\"");
}
else
{
fnPrintf( m_pHRequest, " align=\"left\"");
}
fnPrintf( m_pHRequest, ">\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableDataEnd(void)
{
fnPrintf( m_pHRequest, "</td>\n");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printTableDataEmpty(void)
{
fnPrintf( m_pHRequest, "&nbsp;");
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printErrorPage(
RCODE rc,
FLMBOOL bStdHeader,
const char * pszWhat)
{
printDocStart( "Error", TRUE, bStdHeader);
fnPrintf( m_pHRequest, "<center><h2>\n");
fnPrintf( m_pHRequest, "%s<br>%s (0x%04X).\n", pszWhat, FlmErrorString( rc),
(unsigned) rc);
fnPrintf( m_pHRequest, "</h2></center>\n");
printDocEnd();
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printErrorPage(
const char * pszErrStr,
const char * pszErrStr2,
FLMBOOL bStdHeader)
{
printDocStart( "Error", TRUE, bStdHeader);
fnPrintf( m_pHRequest, "<center><h2>\n");
fnPrintf( m_pHRequest, "%s\n", pszErrStr);
if (pszErrStr2 && *pszErrStr2)
{
fnPrintf( m_pHRequest, "<BR>%s\n", pszErrStr2);
}
fnPrintf( m_pHRequest, "</h2></center>\n");
printDocEnd();
}
/****************************************************************************
Desc: Start an input form
****************************************************************************/
void F_WebPage::printStartInputForm(
const char * pszFormName,
const char * pszPage,
FLMUINT uiFormValue)
{
fnPrintf( m_pHRequest,
"<form name=\"%s\" type=\"submit\" method=\"get\" action=\"%s/%s\">\n"
"<input name=\"Action\" type=\"hidden\" value=\"%u\">\n",
pszFormName, m_pszURLString, pszPage, (unsigned) uiFormValue);
}
/****************************************************************************
Desc: End an input form
****************************************************************************/
void F_WebPage::printEndInputForm(void)
{
fnPrintf( m_pHRequest, "</form>");
}
/****************************************************************************
Desc: Generic function to output HTML that gererates a button
****************************************************************************/
void F_WebPage::printButton(
const char * pszContents,
ButtonTypes eBType,
const char * pszName,
const char * pszValue,
const char * pszExtra,
FLMBOOL bDisabled,
FLMBYTE ucAccessKey,
FLMUINT uiTabIndex)
{
fnPrintf( m_pHRequest, "<BUTTON TYPE=");
switch (eBType)
{
case BT_Submit:
fnPrintf( m_pHRequest, "submit");
break;
case BT_Reset:
fnPrintf( m_pHRequest, "reset");
break;
case BT_Button:
fnPrintf( m_pHRequest, "button");
break;
default:
flmAssert( 0);
}
if (pszName && pszName[0])
{
fnPrintf( m_pHRequest, " NAME=%s", pszName);
}
if (pszValue && pszValue[0])
{
fnPrintf( m_pHRequest, " VALUE=%s", pszValue);
}
if (bDisabled)
{
fnPrintf( m_pHRequest, " DISABLED");
}
if (ucAccessKey != '\0')
{
fnPrintf( m_pHRequest, " ACCESSKEY=%c", ucAccessKey);
}
if (uiTabIndex)
{
fnPrintf( m_pHRequest, " uiTabIndex=%d", uiTabIndex);
}
if (pszExtra)
{
fnPrintf( m_pHRequest, " %s ", pszExtra);
}
fnPrintf( m_pHRequest, ">%s</BUTTON>\n",
(char*) (pszContents ? pszContents : ""));
}
/****************************************************************************
Desc: Format and output date.
****************************************************************************/
void F_WebPage::printDate(
FLMUINT uiGMTTime,
char * pszBuffer)
{
F_TMSTAMP timeStamp;
FLMUINT uiLocalTime;
char * pszAmPm;
const char * pszMonth;
uiLocalTime = (FLMUINT) (uiGMTTime - f_timeGetLocalOffset());
f_timeSecondsToDate( uiLocalTime, &timeStamp);
pszAmPm = (char*) ((timeStamp.hour >= 12) ? (char*) "pm" : (char*) "am");
if (timeStamp.hour > 12)
{
timeStamp.hour -= 12;
}
if (timeStamp.hour == 0)
{
timeStamp.hour = 12;
}
switch (timeStamp.month)
{
case 0:
pszMonth = "Jan";
break;
case 1:
pszMonth = "Feb";
break;
case 2:
pszMonth = "Mar";
break;
case 3:
pszMonth = "Apr";
break;
case 4:
pszMonth = "May";
break;
case 5:
pszMonth = "Jun";
break;
case 6:
pszMonth = "Jul";
break;
case 7:
pszMonth = "Aug";
break;
case 8:
pszMonth = "Sep";
break;
case 9:
pszMonth = "Oct";
break;
case 10:
pszMonth = "Nov";
break;
default:
case 11:
pszMonth = "Dec";
break;
}
if (pszBuffer != NULL)
{
f_sprintf( (char*) pszBuffer, "%s %u, %u %u:%02u:%02u %s", pszMonth,
(unsigned) timeStamp.day, (unsigned) timeStamp.year,
(unsigned) timeStamp.hour, (unsigned) timeStamp.minute,
(unsigned) timeStamp.second, pszAmPm);
}
else
{
fnPrintf( m_pHRequest, "%s %u, %u %u:%02u:%02u %s", pszMonth,
(unsigned) timeStamp.day, (unsigned) timeStamp.year,
(unsigned) timeStamp.hour, (unsigned) timeStamp.minute,
(unsigned) timeStamp.second, pszAmPm);
}
}
/****************************************************************************
Desc: Outputs a Yes or No value based on the passed-in boolean
****************************************************************************/
void F_WebPage::printYesNo(
FLMBOOL bYes)
{
fnPrintf( m_pHRequest, "%s", bYes ? "Yes" : "No");
}
/****************************************************************************
Desc: Outputs a number with commas, for easier reading.
****************************************************************************/
void F_WebPage::printCommaNumText(
FLMUINT64 ui64Num)
{
FLMUINT uiTerm;
FLMUINT64 ui64Divisor = 1;
FLMBOOL bFirstPass = TRUE;
while ((FLMUINT64) (ui64Num / (ui64Divisor * (FLMUINT64) 1000)))
{
ui64Divisor *= 1000;
}
while (ui64Divisor)
{
uiTerm = (FLMUINT) (ui64Num / ui64Divisor);
ui64Num -= ((FLMUINT64) uiTerm) * ui64Divisor;
if (bFirstPass)
{
fnPrintf( m_pHRequest, "%u", (unsigned) uiTerm);
bFirstPass = FALSE;
}
else
{
fnPrintf( m_pHRequest, "%03u", (unsigned) uiTerm);
}
if ((ui64Divisor /= (FLMUINT64) 1000) > (FLMUINT64) 0)
{
fnPrintf( m_pHRequest, ",");
}
}
}
/****************************************************************************
Desc: Outputs a number with commas, for easier reading.
****************************************************************************/
void F_WebPage::printCommaNum(
FLMUINT64 ui64Num,
JustificationType eJustify,
FLMBOOL bChangedValue)
{
printTableDataStart( TRUE, eJustify);
if (bChangedValue)
{
fnPrintf( m_pHRequest, "<font color=red>");
}
printCommaNumText( ui64Num);
if (bChangedValue)
{
fnPrintf( m_pHRequest, "</font>");
}
printTableDataEnd();
}
/****************************************************************************
Desc:
****************************************************************************/
RCODE F_WebPage::acquireSession(void)
{
RCODE rc = FERR_OK;
FLMBOOL bHttpSessionMutexLocked = FALSE;
FLMUINT uiSize;
void * pvHttpSession = NULL;
char szSessionKey[F_SESSION_KEY_LEN];
m_pFlmSession = NULL;
if (!gv_FlmSysData.HttpConfigParms.fnAcquireSession)
{
rc = RC_SET( FERR_NOT_IMPLEMENTED);
goto Exit;
}
if ((pvHttpSession = fnAcquireSession()) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
f_mutexLock( gv_FlmSysData.hHttpSessionMutex);
bHttpSessionMutexLocked = TRUE;
uiSize = sizeof(szSessionKey);
if (fnGetSessionValue( pvHttpSession, FLM_SESSION_ID_NAME,
(void*) szSessionKey, (FLMSIZET *) &uiSize) != 0)
{
CreateSession:
if (RC_BAD( rc = gv_FlmSysData.pSessionMgr->createSession( &m_pFlmSession)))
{
goto Exit;
}
fnSetSessionValue( pvHttpSession, FLM_SESSION_ID_NAME,
m_pFlmSession->getKey(), sizeof(szSessionKey));
}
else
{
if (RC_BAD( rc = gv_FlmSysData.pSessionMgr->getSession( szSessionKey,
&m_pFlmSession)))
{
if (rc == FERR_NOT_FOUND)
{
goto CreateSession;
}
}
}
Exit:
if (RC_BAD( rc))
{
if (m_pFlmSession)
{
releaseSession();
}
}
if (pvHttpSession)
{
fnReleaseSession( pvHttpSession);
}
if (bHttpSessionMutexLocked)
{
f_mutexUnlock( gv_FlmSysData.hHttpSessionMutex);
}
return (rc);
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::releaseSession(void)
{
if (m_pFlmSession)
{
gv_FlmSysData.pSessionMgr->releaseSession( &m_pFlmSession);
m_pFlmSession = NULL;
}
}
/****************************************************************************
Desc:
****************************************************************************/
void F_WebPage::printSpaces(
FLMUINT uiCount)
{
while (uiCount--)
{
fnPrintf( m_pHRequest, "&nbsp;");
}
}
/****************************************************************************
Desc: Outputs elapsed milliseconds as seconds.milli. The optional parameter
pszBuffer will cause the time to be written to pszBuffer instead of the
web page. That way it can be incorporated into more complex structures
if desired.
****************************************************************************/
void F_WebPage::printElapTime(
FLMUINT64 ui64ElapTime,
char* pszBuffer,
JustificationType eJustify,
FLMBOOL bTimeIsMilli)
{
FLMUINT uiHours;
FLMUINT uiMinutes;
FLMUINT uiSeconds;
FLMUINT uiMilli = 0;
if (bTimeIsMilli)
{
uiHours = (FLMUINT) (ui64ElapTime / (FLMUINT64) (1000 * 3600));
uiMinutes = (FLMUINT) ((ui64ElapTime / (FLMUINT64) (1000 * 60)) % (FLMUINT64) 60);
uiSeconds = (FLMUINT) ((ui64ElapTime / (FLMUINT64) 1000) % (FLMUINT64) 60);
uiMilli = (FLMUINT) (ui64ElapTime % (FLMUINT64) 1000);
}
else
{
uiHours = (FLMUINT) (ui64ElapTime / (FLMUINT64) 3600);
uiMinutes = (FLMUINT) ((ui64ElapTime / (FLMUINT64) 60) % (FLMUINT64) 60);
uiSeconds = (FLMUINT) (ui64ElapTime % (FLMUINT64) 60);
}
if (!pszBuffer)
{
printTableDataStart( TRUE, eJustify);
}
if (pszBuffer)
{
f_sprintf( (char*) pszBuffer, "%02u:%02u:%02u", (unsigned) uiHours,
(unsigned) uiMinutes, (unsigned) uiSeconds);
}
else
{
fnPrintf( m_pHRequest, "%02u:%02u:%02u", (unsigned) uiHours,
(unsigned) uiMinutes, (unsigned) uiSeconds);
}
if (bTimeIsMilli)
{
if (pszBuffer)
{
char szTemp[5];
f_sprintf( szTemp, ".%03u", (unsigned) uiMilli);
f_strncat( (char*) pszBuffer, szTemp, 4);
}
else
{
fnPrintf( m_pHRequest, ".%03u", (unsigned) uiMilli);
}
}
if (!pszBuffer)
{
printTableDataEnd();
}
}
/****************************************************************************
Desc: This function will output a form in an already existing page that will
present a formatted display of the record passed in. An optional parameter
bReadOnly will determine if the form should allow editing of the record
or not. The default value is TRUE (No editing capability). A null may
be passed in for the FlmRecord pointer, in which case an empty display
will be created. Normally, a bReadOnly value of false would accompany
a null record so that a record can be created. The printRecordStyle()
must be called in the header section of the page prior to calling this
function. Multiple calls may be made to display multiple records per page.
The puiContext parameter must be initialized to zero before the first
(and possibly the only) call, otherwise the scripts need to run this page
will not be loaded.
****************************************************************************/
void F_WebPage::printRecord(
const char * pszDbKey,
FlmRecord * pRec,
F_NameTable * pNameTable,
FLMUINT * puiContext,
FLMBOOL bReadOnly,
FLMUINT uiSelectedField,
FLMUINT uiFlags)
{
#define SP "&nbsp;"
FLMBOOL bEmpty = FALSE;
FLMUINT uiContainer;
FLMUINT uiDrn;
void * pvField;
FLMUINT uiFieldCounter;
FLMUINT uiFldCnt;
FLMUINT uiTagNum;
FLMUINT uiLevel;
FLMUINT uiType;
FLMUINT uiContext = 0;
char szNameBuf[128];
flmAssert( pNameTable);
if (puiContext)
{
uiContext = *puiContext;
(*puiContext)++;
}
// See if we need to write out the scripts
if (uiContext == 0)
{
printRecordScripts();
}
if (!pRec)
{
bEmpty = TRUE;
uiDrn = 0;
uiContainer = 0;
}
else
{
// Get the Drn & Container
uiDrn = pRec->getID();
uiContainer = pRec->getContainerID();
}
// Count the fields
uiFldCnt = 0;
if (pRec != NULL)
{
pvField = pRec->root();
while (pvField)
{
pvField = pRec->next( pvField);
uiFldCnt++;
}
}
// Begin the form that displays the record data (if any)
fnPrintf( m_pHRequest,
"<form name=\"Record%d\" method=\"post\" action=\"%s/ProcessRecord\">\n",
uiContext, gv_FlmSysData.HttpConfigParms.pszURLString);
printHiddenField( "ReadOnly", (char*) (bReadOnly ? "TRUE" : "FALSE"));
if (pszDbKey)
{
printHiddenField( "dbhandle", (char*) (pszDbKey));
}
printHiddenField( (char*) "Action", "none");
printHiddenField( (char*) "FieldLevel", (FLMUINT) 0);
printHiddenField( (char*) "FieldNumber", (FLMUINT) 0);
printHiddenField( (char*) "FieldCount", uiFldCnt);
// Print out the block that displays the DRN and Container list
fnPrintf( m_pHRequest, "<div id=\"recordselect\">\n");
fnPrintf( m_pHRequest,
"<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" width=\"170\" "
"frame=\"box\">\n");
fnPrintf( m_pHRequest, "<tr>\n<td align=right>DRN&nbsp;<input name=\"DRN\" "
"type=\"text\" value=\"%u\" size=10 maxlength=20 %s>&nbsp;</td>\n</tr>\n",
uiDrn, pszDbKey == NULL ? "disabled" : "");
if (pszDbKey != NULL)
{
fnPrintf( m_pHRequest, "<tr>\n<td align=right>Flags&nbsp;\n");
printRetrievalFlagsPulldown( uiFlags);
fnPrintf( m_pHRequest, "</td>\n</tr>\n");
}
fnPrintf( m_pHRequest, "<tr>\n<td align=right>Container&nbsp;\n");
if (pszDbKey != NULL)
{
printContainerPulldown( pNameTable, uiContainer);
}
else
{
fnPrintf( m_pHRequest,
"<input name=\"container\" type=\"text\" value=\"%u\" "
"size=10 maxlength=20 disabled>&nbsp;</td>\n</tr>\n", uiContainer);
}
fnPrintf( m_pHRequest, "</td>\n</tr>\n");
if (pszDbKey != NULL)
{
// Print out the field list drop down box.
fnPrintf( m_pHRequest, "<tr>\n<td align=left nowrap>Field list&nbsp;");
printFieldPulldown( pNameTable, uiSelectedField);
fnPrintf( m_pHRequest, "</td>\n</tr>\n");
// Print out the Add, Modify, Delete action buttons.
fnPrintf( m_pHRequest,
"<tr><td align=left><input type=\"button\" value=\"new record\" "
"onClick=\"doNewRecord(document.Record%u)\">", uiContext);
if (pRec != NULL)
{
if (!bReadOnly)
{
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"add\" "
"onClick=\"doAddRecord(document.Record%u)\">", uiContext);
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"modify\" "
"onClick=\"doModRecord(document.Record%u)\">", uiContext);
}
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"delete\" "
"onClick=\"doDelRecord(document.Record%u)\">", uiContext);
}
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"retrieve\" "
"onClick=\"doRetrieveRecord(document.Record%u)\">", uiContext);
if (pRec != NULL && bReadOnly)
{
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"edit record\" "
"onClick=\"doEdit(document.Record%u)\">", uiContext);
}
fnPrintf( m_pHRequest, "</td></tr>\n");
}
fnPrintf( m_pHRequest, "</table>\n</div>\n");
// Print out the record fields (if there are any)
if (pRec != NULL)
{
fnPrintf( m_pHRequest, "<div id=\"fieldcontrol\">\n");
if (!bReadOnly)
{
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"ins-c\" "
"onClick=\"doInsertChild(document.Record%u)\">", uiContext);
if (uiFldCnt > 1)
{
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"ins-s\" "
"onClick=\"doInsertSibling(document.Record%u)\">", uiContext);
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"copy\" "
"onClick=\"doCopy(document.Record%u)\">", uiContext);
fnPrintf( m_pHRequest, "<input type=\"button\" value=\"clip\" "
"onClick=\"doClip(document.Record%u)\">\n", uiContext);
}
}
fnPrintf( m_pHRequest, "<pre>\n");
// Now for the actual data. Start with the root field.
pvField = pRec->root();
uiFieldCounter = 0;
while (pvField)
{
uiTagNum = pRec->getFieldID( pvField);
uiLevel = pRec->getLevel( pvField);
uiType = pRec->getDataType( pvField);
if (uiLevel != 0 && !bReadOnly)
{
fnPrintf( m_pHRequest,
"<input name=\"radioSel\" type=\"radio\" value=\"%u\" "
"onClick=\"setFieldLevel(document.Record%u, %u, %u)\">",
uiFieldCounter, uiContext, uiFieldCounter, uiLevel);
}
pNameTable->getFromTagNum( uiTagNum, NULL, szNameBuf, sizeof(szNameBuf));
printSpaces( uiLevel + 5);
fnPrintf( m_pHRequest, "%s<font color=black>%d</font>%s%s%s", SP,
uiLevel, SP, szNameBuf, SP);
if (pRec->getDataLength( pvField))
{
switch (uiType)
{
case FLM_TEXT_TYPE:
printTextField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
case FLM_NUMBER_TYPE:
printNumberField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
case FLM_BINARY_TYPE:
printBinaryField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
case FLM_CONTEXT_TYPE:
printContextField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
case FLM_BLOB_TYPE:
printBlobField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
default:
printDefaultField( pRec, pvField, uiFieldCounter, bReadOnly);
break;
}
}
else if (!bReadOnly)
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"\" size=\"%d\">",
uiFieldCounter, MAX_FIELD_SIZE( 0));
}
// Print the hidden field Ids
printFieldIds( uiFieldCounter, uiLevel, uiType, uiTagNum);
fnPrintf( m_pHRequest, "\n");
pvField = pRec->next( pvField);
uiFieldCounter++;
}
fnPrintf( m_pHRequest, "</pre>\n</div>\n<hr width=75%%>\n");
}
fnPrintf( m_pHRequest, "</form>\n");
return;
}
/****************************************************************************
Desc: Prints out a style sheet specific to displaying records.
****************************************************************************/
void F_WebPage::printRecordStyle(void)
{
fnPrintf( m_pHRequest, "<style media=\"screen\" type=\"text/css\"><!--\n");
fnPrintf( m_pHRequest, "#recordselect { background-color: #e8e8e8; "
"position: relative; left: 15px; width: 150px; visibility: visible}\n");
fnPrintf( m_pHRequest, "#fieldlist { position: relative; width: 200px; "
"visibility: visible}\n");
fnPrintf( m_pHRequest, "#fieldcontrol { background-color: #e5e5e5; "
"color: #357977; font-weight: bold; position: relative; top: 5px; "
"left: 15px; visibility: visible}\n");
fnPrintf( m_pHRequest, ".fieldclass { color: #0db3ae }\n--></style>\n");
}
/****************************************************************************
Desc: Prints out the required scripts for displaying and updating records.
****************************************************************************/
void F_WebPage::printRecordScripts( void)
{
fnPrintf( m_pHRequest, "<script><!-- Hide script from old browsers\n");
fnPrintf( m_pHRequest, "function doEdit(myForm)\n"
"{\n"
"myForm.Action.value=\"Retrieve\";\n"
"myForm.ReadOnly.value = \"FALSE\";\n"
"myForm.submit();\n"
"}\n");
fnPrintf( m_pHRequest, "function confirmAction(action)\n"
"{\n"
"return confirm(\"Are you sure you want to \" + action + \" this record?\");\n"
"}\n");
fnPrintf( m_pHRequest, "function doAddRecord(myForm)\n"
"{\n"
"if (confirmAction(\"Add\"))\n"
"{\n"
"myForm.Action.value=\"Add\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doNewRecord(myForm)\n"
"{\n"
"myForm.ReadOnly.value=\"FALSE\";\n"
"myForm.Action.value=\"New\";\n"
"myForm.submit();\n"
"}\n");
fnPrintf( m_pHRequest, "function doModRecord(myForm)\n"
"{\n"
"if (confirmAction(\"Modify\"))\n"
"{\n"
"myForm.Action.value=\"Modify\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doDelRecord(myForm)\n"
"{\n"
"if (confirmAction(\"Delete\"))\n"
"{\n"
"myForm.Action.value=\"Delete\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doRetrieveRecord(myForm)\n"
"{\n"
"myForm.ReadOnly.value=\"TRUE\";\n"
"myForm.Action.value=\"Retrieve\";\n"
"myForm.submit();\n"
"}\n");
fnPrintf( m_pHRequest, "function doInsertSibling(myForm)\n"
"{\n"
"if (validateFieldLevel(myForm))\n"
"{\n"
"myForm.Action.value=\"InsertSibling\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doInsertChild(myForm)\n"
"{\n"
"if (validateFieldLevel(myForm))\n"
"{\n"
"myForm.Action.value=\"InsertChild\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doCopy(myForm)\n"
"{\n"
"if (validateFieldLevel(myForm))\n"
"{\n"
"myForm.Action.value=\"Copy\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function doClip(myForm)\n"
"{\n"
"if (validateFieldLevel(myForm))\n"
"{\n"
"myForm.Action.value=\"Clip\";\n"
"myForm.submit();\n"
"}\n"
"}\n");
fnPrintf( m_pHRequest, "function validateFieldLevel(myForm)\n"
"{\n"
"if (myForm.FieldCount.value>1)\n"
"{\n"
"if ((myForm.FieldLevel.value==0)||(myForm.FieldNumber.value==0))\n"
"{\n"
"alert(\"You must select a field radio button\");\n"
"return false;\n"
"}\n"
"}\n"
"return true;\n"
"}\n");
fnPrintf( m_pHRequest, "function setFieldLevel(myForm,field,level)\n"
"{\n"
"myForm.FieldLevel.value=level;\n"
"myForm.FieldNumber.value=field;\n"
"}\n");
fnPrintf( m_pHRequest, "// End hiding here -->\n</script>\n");
}
/****************************************************************************
Desc: Prints out a hidden field with a character string value
****************************************************************************/
void F_WebPage::printHiddenField(
const char * pszName,
const char * pszValue)
{
fnPrintf( m_pHRequest, "<input name=\"%s\" type=\"hidden\" value=\"%s\">",
pszName, pszValue);
}
//
/****************************************************************************
Desc: Prints out a hidden with an unsigned long value
****************************************************************************/
void F_WebPage::printHiddenField(
const char * pszName,
FLMUINT uiValue)
{
fnPrintf( m_pHRequest, "<input name=\"%s\" type=\"hidden\" value=\"%u\">",
pszName, (unsigned) uiValue);
}
//
/****************************************************************************
Desc: Prints out the value for the field, assuming the field is a text field.
****************************************************************************/
void F_WebPage::printTextField(
FlmRecord * pRec,
void * pvField,
FLMUINT uiFieldCounter,
FLMBOOL bReadOnly)
{
RCODE rc = FERR_OK;
FLMUNICODE * puzBuf = NULL;
FLMUNICODE * puzTmp = NULL;
F_DynamicBuffer * pBuffer = NULL;
FLMUINT uiLen;
if (RC_BAD( rc = pRec->getUnicodeLength( pvField, &uiLen)))
{
fnPrintf( m_pHRequest,
"** Error retrieving Unicode field length (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
// The length returned does not allow for 2 NULL terminators. We must
// allow for them when allocating a buffer.
uiLen += 2;
if (RC_BAD( rc = f_alloc( uiLen, &puzBuf)))
{
fnPrintf( m_pHRequest,
"** Error allocating memory buffer (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
if (RC_BAD( rc = pRec->getUnicode( pvField, puzBuf, &uiLen)))
{
fnPrintf( m_pHRequest,
"** Error retrieving Unicode field (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
puzTmp = puzBuf;
if ((pBuffer = f_new F_DynamicBuffer) == NULL)
{
fnPrintf( m_pHRequest, "** Error allocating memory **");
goto Exit;
}
// Start the text field if not read only mode.
if (!bReadOnly)
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"",
uiFieldCounter);
}
else
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">");
}
while (*puzTmp)
{
// Check for ASCII characters
if ((*puzTmp >= 32) && (*puzTmp <= 126))
{
if (RC_BAD( rc = pBuffer->addChar( (char) *puzTmp)))
{
fnPrintf( m_pHRequest,
"** Error adding Unicode character to buffer (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
}
else
{
// Treat as though these are NON-ASCII. They will be printed in
// the form ~[0x ]
char szTempBuff[20];
f_sprintf( szTempBuff, "~[0x%04X]", (unsigned) (*puzTmp));
if (RC_BAD( rc = pBuffer->addString( szTempBuff)))
{
fnPrintf( m_pHRequest,
"** Error formatting Unicode string (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
}
// We are attempting to not let our buffer get any larger than the
// Http stack buffer size. We don't really know what the limit is,
// but we are using what seems to reasonable to us...
if ((pBuffer->getBufferSize() + 9) >= RESP_WRITE_BUF_SIZE)
{
fnPrintf( m_pHRequest, "%s", pBuffer->printBuffer());
pBuffer->reset();
}
puzTmp++;
}
if (bReadOnly)
{
fnPrintf( m_pHRequest, "%s</font>", pBuffer->printBuffer());
}
else
{
fnPrintf( m_pHRequest, "%s\" size=\"%d\">", pBuffer->printBuffer(),
MAX_FIELD_SIZE( uiLen));
}
Exit:
if (puzBuf)
{
f_free( &puzBuf);
}
if (pBuffer)
{
pBuffer->Release();
}
}
//
/****************************************************************************
Desc: Prints out the value for the field, assuming the field is a number field.
****************************************************************************/
void F_WebPage::printNumberField(
FlmRecord * pRec,
void * pvField,
FLMUINT uiFieldCounter,
FLMBOOL bReadOnly)
{
RCODE rc = FERR_OK;
FLMINT iVal;
FLMUINT uiVal;
if (RC_BAD( rc = pRec->getUINT( pvField, &uiVal)))
{
if (RC_OK( rc = pRec->getINT( pvField, &iVal)))
{
if (bReadOnly)
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">%d</font>", (int) iVal);
}
else
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"%d\" size=\"%d\">",
uiFieldCounter, (int) iVal, MAX_FIELD_SIZE( 0));
}
}
else
{
fnPrintf( m_pHRequest,
"** Error retrieving number field (Return Code = 0x%04X, %s)**\n",
(unsigned) rc, FlmErrorString( rc));
}
}
else
{
if (bReadOnly)
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">%lu</font>",
(unsigned long) uiVal);
}
else
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"%lu\" size=\"20\">",
uiFieldCounter, (unsigned long) uiVal);
}
}
}
/****************************************************************************
Desc: Prints out the value for the field, assuming the field is a binary field.
****************************************************************************/
void F_WebPage::printBinaryField(
FlmRecord * pRec,
void * pvField,
FLMUINT uiFieldCounter,
FLMBOOL bReadOnly)
{
RCODE rc = FERR_OK;
FLMBYTE * pucBuf = NULL;
FLMBYTE * pszTmpBuf = NULL;
FLMBYTE * pszTmp = NULL;
FLMUINT uiLoop;
FLMUINT uiLen;
FLMUINT uiBufLen;
uiLen = pRec->getDataLength( pvField);
if (RC_BAD( rc = f_alloc( uiLen, &pucBuf)))
{
fnPrintf( m_pHRequest,
"** Error occured allocating memory to retrieve binary field (Return Code = 0x%04X, %s) **\n",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
if (RC_BAD( rc = pRec->getBinary( pvField, pucBuf, &uiLen)))
{
if (rc != FERR_NOT_FOUND)
{
fnPrintf( m_pHRequest,
"** Error occured retrieving binary field (Return Code = 0x%04X, %s) **\n",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
}
if (RC_BAD( rc = f_alloc( RESP_WRITE_BUF_SIZE + 1, &pszTmpBuf)))
{
fnPrintf( m_pHRequest,
"** Error occured allocating memory to format binary field (Return Code = 0x%04X, %s) **\n",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
if (!bReadOnly)
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"",
uiFieldCounter);
}
else
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">");
}
// Scan through the binary data, present all data as Hex.
for (pszTmp = pszTmpBuf, uiLoop = 0, uiBufLen = 0; uiLoop < uiLen; uiLoop++)
{
if (uiLoop)
{
*pszTmp++ = ' ';
uiBufLen++;
}
f_sprintf( (char*) pszTmp, "%2.2X", (unsigned) pucBuf[uiLoop]);
pszTmp += 2;
uiBufLen += 2;
if ((uiBufLen + 3) >= RESP_WRITE_BUF_SIZE)
{
// Flush the current buffer
*pszTmp = '\0';
fnPrintf( m_pHRequest, "%s", pszTmpBuf);
pszTmp = pszTmpBuf;
uiBufLen = 0;
}
}
*pszTmp = '\0';
if (bReadOnly)
{
fnPrintf( m_pHRequest, "%s</font>", pszTmpBuf);
}
else
{
fnPrintf( m_pHRequest, "%s\" size=\"%d\">", pszTmpBuf,
MAX_FIELD_SIZE( uiLen * 3));
}
Exit:
if (pucBuf)
{
f_free( &pucBuf);
}
if (pszTmpBuf)
{
f_free( &pszTmpBuf);
}
}
/****************************************************************************
Desc: Prints out the value for the field, assuming the field is a context field.
****************************************************************************/
void F_WebPage::printContextField(
FlmRecord * pRec,
void * pvField,
FLMUINT uiFieldCounter,
FLMBOOL bReadOnly)
{
RCODE rc = FERR_OK;
FLMUINT uiRecPointer;
if (RC_OK( rc = pRec->getRecPointer( pvField, &uiRecPointer)))
{
if (bReadOnly)
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">%lu</font>",
(unsigned long) uiRecPointer);
}
else
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" "
"value=\"%lu\" size=\"d\">", uiFieldCounter,
(unsigned long) uiRecPointer, MAX_FIELD_SIZE( 0));
}
}
else
{
fnPrintf( m_pHRequest,
"** Error retrieving context field (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
}
}
/****************************************************************************
Desc: Prints out the value for the field, assuming the field is a blob field.
****************************************************************************/
void F_WebPage::printBlobField(
FlmRecord * pRec,
void * pvField,
FLMUINT uiFieldCounter,
FLMBOOL bReadOnly)
{
RCODE rc = FERR_OK;
FlmBlob * pBlob = NULL;
char szPath[F_PATH_MAX_SIZE];
FLMUINT uiLen;
if (RC_BAD( rc = pRec->getBlob( pvField, &pBlob)))
{
fnPrintf( m_pHRequest,
"** Failed to retrieve Blob object (Return Code = 0x%04X, %s) **",
(unsigned long) rc, FlmErrorString( rc));
goto Exit;
}
uiLen = ((FlmBlobImp *) pBlob)->getDataLength();
if (uiLen == 0)
{
if (!bReadOnly)
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" "
"value=\"\" size=\"%d\">", uiFieldCounter,
MAX_FIELD_SIZE( 0));
}
goto Exit;
}
if (RC_BAD( rc = pBlob->buildFileName( szPath)))
{
fnPrintf( m_pHRequest,
"** Failed to retrieve Blob filename (Return Code = 0x%04X, %s) **",
(unsigned) rc, FlmErrorString( rc));
goto Exit;
}
if (bReadOnly)
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">");
printEncodedString( szPath, HTML_ENCODING);
fnPrintf( m_pHRequest, "</font>");
}
else
{
fnPrintf( m_pHRequest,
"<input class=\"fieldclass\" name=\"field%d\" type=\"text\" value=\"",
uiFieldCounter);
printEncodedString( szPath, HTML_ENCODING);
fnPrintf( m_pHRequest, "\" size=\"20\">");
}
Exit:
if (pBlob)
{
pBlob->Release();
}
}
/****************************************************************************
Desc: Prints out a string identifying this as a default field - error condition.
****************************************************************************/
void F_WebPage::printDefaultField(
FlmRecord *,
void *,
FLMUINT,
FLMBOOL)
{
fnPrintf( m_pHRequest, "<font color=\"0db3ae\">**Default Field**</font>");
}
/****************************************************************************
Desc: Prints out the hidden field identifiers
****************************************************************************/
void F_WebPage::printFieldIds(
FLMUINT uiFieldCounter,
FLMUINT uiFieldLevel,
FLMUINT uiType,
FLMUINT uiTagNum)
{
char szTmp[20];
f_sprintf( szTmp, "fieldLevel%u", (unsigned) uiFieldCounter);
printHiddenField( szTmp, uiFieldLevel);
f_sprintf( szTmp, "fieldType%u", (unsigned) uiFieldCounter);
printHiddenField( szTmp, uiType);
f_sprintf( szTmp, "fieldTag%u", (unsigned) uiFieldCounter);
printHiddenField( szTmp, uiTagNum);
}
/****************************************************************************
Desc: Prints a table listing the fields of the supplied Log Headers. Any of
the log header pointers may be null, in which case a series of blank
entries will be created in the table for that entry.
****************************************************************************/
void F_WebPage::printLogHeaders(
FLMBYTE * pucLastCommitted,
FLMBYTE * pucCheckpoint,
FLMBYTE * pucUncommitted)
{
FLMBOOL bHighlight = FALSE;
// Start the table and headings...
printTableStart( NULL, 5, 100);
printTableRowStart( FALSE);
printColumnHeading( "Offset (hex)");
printColumnHeading( "Field");
printColumnHeading( "Last Committed");
printColumnHeading( "Checkpoint");
printColumnHeading( "Uncommitted");
printTableRowEnd();
// Fill in the table here. LOG_RFL_FILE_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_FILE_NUM);
fnPrintf( m_pHRequest, "<td>Current RFL file</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_FILE_NUM);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_FILE_NUM);
printLogFileEntryUD( pucUncommitted, LOG_RFL_FILE_NUM);
printTableRowEnd();
// LOG_RFL_LAST_TRANS_OFFSET
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_LAST_TRANS_OFFSET);
fnPrintf( m_pHRequest, "<td>Current RFL offset</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_LAST_TRANS_OFFSET);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_LAST_TRANS_OFFSET);
printLogFileEntryUD( pucUncommitted, LOG_RFL_LAST_TRANS_OFFSET);
printTableRowEnd();
// LOG_RFL_LAST_CP_FILE_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_LAST_CP_FILE_NUM);
fnPrintf( m_pHRequest, "<td>Last CP RFL file</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_LAST_CP_FILE_NUM);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_LAST_CP_FILE_NUM);
printLogFileEntryUD( pucUncommitted, LOG_RFL_LAST_CP_FILE_NUM);
printTableRowEnd();
// LOG_RFL_LAST_CP_OFFSET
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_LAST_CP_OFFSET);
fnPrintf( m_pHRequest, "<td>Last CP RFL offset</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_LAST_CP_OFFSET);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_LAST_CP_OFFSET);
printLogFileEntryUD( pucUncommitted, LOG_RFL_LAST_CP_OFFSET);
printTableRowEnd();
// LOG_ROLLBACK_EOF
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_ROLLBACK_EOF);
fnPrintf( m_pHRequest, "<td>End of file</td>");
printLogFileEntryUD( pucLastCommitted, LOG_ROLLBACK_EOF);
printLogFileEntryUD( pucCheckpoint, LOG_ROLLBACK_EOF);
printLogFileEntryUD( pucUncommitted, LOG_ROLLBACK_EOF);
printTableRowEnd();
// LOG_INC_BACKUP_SEQ_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_INC_BACKUP_SEQ_NUM);
fnPrintf( m_pHRequest, "<td>Incremental backup sequence number</td>");
printLogFileEntryUD( pucLastCommitted, LOG_INC_BACKUP_SEQ_NUM);
printLogFileEntryUD( pucCheckpoint, LOG_INC_BACKUP_SEQ_NUM);
printLogFileEntryUD( pucUncommitted, LOG_INC_BACKUP_SEQ_NUM);
printTableRowEnd();
// LOG_CURR_TRANS_ID
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_CURR_TRANS_ID);
fnPrintf( m_pHRequest, "<td>Transaction ID</td>");
printLogFileEntryUD( pucLastCommitted, LOG_CURR_TRANS_ID);
printLogFileEntryUD( pucCheckpoint, LOG_CURR_TRANS_ID);
printLogFileEntryUD( pucUncommitted, LOG_CURR_TRANS_ID);
printTableRowEnd();
// LOG_COMMIT_COUNT
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_COMMIT_COUNT);
fnPrintf( m_pHRequest, "<td>Commit count</td>");
printLogFileEntryUD( pucLastCommitted, LOG_COMMIT_COUNT);
printLogFileEntryUD( pucCheckpoint, LOG_COMMIT_COUNT);
printLogFileEntryUD( pucUncommitted, LOG_COMMIT_COUNT);
printTableRowEnd();
// LOG_PL_FIRST_CP_BLOCK_ADDR
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_PL_FIRST_CP_BLOCK_ADDR);
fnPrintf( m_pHRequest, "<td>First CP block address</td>");
printLogFileEntryUDX( pucLastCommitted, LOG_PL_FIRST_CP_BLOCK_ADDR);
printLogFileEntryUDX( pucCheckpoint, LOG_PL_FIRST_CP_BLOCK_ADDR);
printLogFileEntryUDX( pucUncommitted, LOG_PL_FIRST_CP_BLOCK_ADDR);
printTableRowEnd();
// LOG_LAST_RFL_FILE_DELETED
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LAST_RFL_FILE_DELETED);
fnPrintf( m_pHRequest, "<td>Last RFL file deleted</td>");
printLogFileEntryUD( pucLastCommitted, LOG_LAST_RFL_FILE_DELETED);
printLogFileEntryUD( pucCheckpoint, LOG_LAST_RFL_FILE_DELETED);
printLogFileEntryUD( pucUncommitted, LOG_LAST_RFL_FILE_DELETED);
printTableRowEnd();
// LOG_RFL_MIN_FILE_SIZE
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_MIN_FILE_SIZE);
fnPrintf( m_pHRequest, "<td>Minimum RFL file size</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_MIN_FILE_SIZE);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_MIN_FILE_SIZE);
printLogFileEntryUD( pucUncommitted, LOG_RFL_MIN_FILE_SIZE);
printTableRowEnd();
// LOG_HDR_CHECKSUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_HDR_CHECKSUM);
fnPrintf( m_pHRequest, "<td>Header checksum</td>");
printLogFileEntryUW( pucLastCommitted, LOG_HDR_CHECKSUM);
printLogFileEntryUW( pucCheckpoint, LOG_HDR_CHECKSUM);
printLogFileEntryUW( pucUncommitted, LOG_HDR_CHECKSUM);
printTableRowEnd();
// LOG_FLAIM_VERSION
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_FLAIM_VERSION);
fnPrintf( m_pHRequest, "<td>Flaim version</td>");
printLogFileEntryUW( pucLastCommitted, LOG_FLAIM_VERSION);
printLogFileEntryUW( pucCheckpoint, LOG_FLAIM_VERSION);
printLogFileEntryUW( pucUncommitted, LOG_FLAIM_VERSION);
printTableRowEnd();
// LOG_LAST_BACKUP_TRANS_ID
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LAST_BACKUP_TRANS_ID);
fnPrintf( m_pHRequest, "<td>Last backup trans ID</td>");
printLogFileEntryUD( pucLastCommitted, LOG_LAST_BACKUP_TRANS_ID);
printLogFileEntryUD( pucCheckpoint, LOG_LAST_BACKUP_TRANS_ID);
printLogFileEntryUD( pucUncommitted, LOG_LAST_BACKUP_TRANS_ID);
printTableRowEnd();
// LOG_BLK_CHG_SINCE_BACKUP
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_BLK_CHG_SINCE_BACKUP);
fnPrintf( m_pHRequest, "<td>Blocks changed since backup</td>");
printLogFileEntryUD( pucLastCommitted, LOG_BLK_CHG_SINCE_BACKUP);
printLogFileEntryUD( pucCheckpoint, LOG_BLK_CHG_SINCE_BACKUP);
printLogFileEntryUD( pucUncommitted, LOG_BLK_CHG_SINCE_BACKUP);
printTableRowEnd();
// LOG_LAST_CP_TRANS_ID
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LAST_CP_TRANS_ID);
fnPrintf( m_pHRequest, "<td>Last CP trans ID</td>");
printLogFileEntryUD( pucLastCommitted, LOG_LAST_CP_TRANS_ID);
printLogFileEntryUD( pucCheckpoint, LOG_LAST_CP_TRANS_ID);
printLogFileEntryUD( pucUncommitted, LOG_LAST_CP_TRANS_ID);
printTableRowEnd();
// LOG_PF_FIRST_BACKCHAIN
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_PF_FIRST_BACKCHAIN);
fnPrintf( m_pHRequest, "<td>Backchain block address</td>");
if (pucLastCommitted &&
FB2UD( &pucLastCommitted[LOG_PF_FIRST_BACKCHAIN]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucLastCommitted, LOG_PF_FIRST_BACKCHAIN);
}
if (pucCheckpoint &&
FB2UD( &pucCheckpoint[LOG_PF_FIRST_BACKCHAIN]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucCheckpoint, LOG_PF_FIRST_BACKCHAIN);
}
if (pucUncommitted &&
FB2UD( &pucUncommitted[LOG_PF_FIRST_BACKCHAIN]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucUncommitted, LOG_PF_FIRST_BACKCHAIN);
}
printTableRowEnd();
// LOG_PF_AVAIL_BLKS
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_PF_AVAIL_BLKS);
fnPrintf( m_pHRequest, "<td>Available blocks</td>");
if (pucLastCommitted &&
FB2UD( &pucLastCommitted[LOG_PF_AVAIL_BLKS]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucLastCommitted, LOG_PF_AVAIL_BLKS);
}
if (pucCheckpoint && FB2UD( &pucCheckpoint[LOG_PF_AVAIL_BLKS]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucCheckpoint, LOG_PF_AVAIL_BLKS);
}
if (pucUncommitted && FB2UD( &pucUncommitted[LOG_PF_AVAIL_BLKS]) == BT_END)
{
fnPrintf( m_pHRequest, "<td>none</td>");
}
else
{
printLogFileEntryUDX( pucUncommitted, LOG_PF_AVAIL_BLKS);
}
printTableRowEnd();
// LOG_LOGICAL_EOF
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LOGICAL_EOF);
fnPrintf( m_pHRequest, "<td>Logical EOF</td>");
printLogFileEntryUD_X( pucLastCommitted, LOG_LOGICAL_EOF);
printLogFileEntryUD_X( pucCheckpoint, LOG_LOGICAL_EOF);
printLogFileEntryUD_X( pucUncommitted, LOG_LOGICAL_EOF);
printTableRowEnd();
// LOG_LAST_RFL_COMMIT_ID
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LAST_RFL_COMMIT_ID);
fnPrintf( m_pHRequest, "<td>Last RFL commit ID</td>");
printLogFileEntryUD( pucLastCommitted, LOG_LAST_RFL_COMMIT_ID);
printLogFileEntryUD( pucCheckpoint, LOG_LAST_RFL_COMMIT_ID);
printLogFileEntryUD( pucUncommitted, LOG_LAST_RFL_COMMIT_ID);
printTableRowEnd();
// LOG_KEEP_ABORTED_TRANS_IN_RFL
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_KEEP_ABORTED_TRANS_IN_RFL);
fnPrintf( m_pHRequest, "<td>Keep aborted trans in RFL</td>");
printLogFileEntryBool( pucLastCommitted, LOG_KEEP_ABORTED_TRANS_IN_RFL);
printLogFileEntryBool( pucCheckpoint, LOG_KEEP_ABORTED_TRANS_IN_RFL);
printLogFileEntryBool( pucUncommitted, LOG_KEEP_ABORTED_TRANS_IN_RFL);
printTableRowEnd();
// LOG_PF_FIRST_BC_CNT
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_PF_FIRST_BC_CNT);
fnPrintf( m_pHRequest, "<td>First BC count</td>");
printLogFileEntryUC( pucLastCommitted, LOG_PF_FIRST_BC_CNT);
printLogFileEntryUC( pucCheckpoint, LOG_PF_FIRST_BC_CNT);
printLogFileEntryUC( pucUncommitted, LOG_PF_FIRST_BC_CNT);
printTableRowEnd();
// LOG_KEEP_RFL_FILES
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_KEEP_RFL_FILES);
fnPrintf( m_pHRequest, "<td>Keep RFL files</td>");
printLogFileEntryBool( pucLastCommitted, LOG_KEEP_RFL_FILES);
printLogFileEntryBool( pucCheckpoint, LOG_KEEP_RFL_FILES);
printLogFileEntryBool( pucUncommitted, LOG_KEEP_RFL_FILES);
printTableRowEnd();
// LOG_AUTO_TURN_OFF_KEEP_RFL
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_AUTO_TURN_OFF_KEEP_RFL);
fnPrintf( m_pHRequest, "<td>Auto turn off keep RFL</td>");
printLogFileEntryBool( pucLastCommitted, LOG_AUTO_TURN_OFF_KEEP_RFL);
printLogFileEntryBool( pucCheckpoint, LOG_AUTO_TURN_OFF_KEEP_RFL);
printLogFileEntryBool( pucUncommitted, LOG_AUTO_TURN_OFF_KEEP_RFL);
printTableRowEnd();
// LOG_PF_NUM_AVAIL_BLKS
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_PF_NUM_AVAIL_BLKS);
fnPrintf( m_pHRequest, "<td>Avail Blocks</td>");
printLogFileEntryUD( pucLastCommitted, LOG_PF_NUM_AVAIL_BLKS);
printLogFileEntryUD( pucCheckpoint, LOG_PF_NUM_AVAIL_BLKS);
printLogFileEntryUD( pucUncommitted, LOG_PF_NUM_AVAIL_BLKS);
printTableRowEnd();
// LOG_RFL_MAX_FILE_SIZE
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_MAX_FILE_SIZE);
fnPrintf( m_pHRequest, "<td>Max file size</td>");
printLogFileEntryUD( pucLastCommitted, LOG_RFL_MAX_FILE_SIZE);
printLogFileEntryUD( pucCheckpoint, LOG_RFL_MAX_FILE_SIZE);
printLogFileEntryUD( pucUncommitted, LOG_RFL_MAX_FILE_SIZE);
printTableRowEnd();
// LOG_DB_SERIAL_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_DB_SERIAL_NUM);
fnPrintf( m_pHRequest, "<td>DB serial number</td>");
printSerialNum( pucLastCommitted ? &pucLastCommitted[LOG_DB_SERIAL_NUM] : NULL);
printSerialNum( pucCheckpoint ? &pucCheckpoint[LOG_DB_SERIAL_NUM] : NULL);
printSerialNum( pucUncommitted ? &pucUncommitted[LOG_DB_SERIAL_NUM] : NULL);
printTableRowEnd();
// LOG_LAST_TRANS_RFL_SERIAL_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_LAST_TRANS_RFL_SERIAL_NUM);
fnPrintf( m_pHRequest, "<td>Last Trans RFL serial number</td>");
printSerialNum( pucLastCommitted ? &pucLastCommitted[LOG_LAST_TRANS_RFL_SERIAL_NUM] :
NULL);
printSerialNum( pucCheckpoint ? &pucCheckpoint[LOG_LAST_TRANS_RFL_SERIAL_NUM] : NULL);
printSerialNum( pucUncommitted ? &pucUncommitted[LOG_LAST_TRANS_RFL_SERIAL_NUM] : NULL);
printTableRowEnd();
// LOG_RFL_NEXT_SERIAL_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_RFL_NEXT_SERIAL_NUM);
fnPrintf( m_pHRequest, "<td>Next RFL serial number</td>");
printSerialNum( pucLastCommitted ? &pucLastCommitted[LOG_RFL_NEXT_SERIAL_NUM] : NULL);
printSerialNum( pucCheckpoint ? &pucCheckpoint[LOG_RFL_NEXT_SERIAL_NUM] : NULL);
printSerialNum( pucUncommitted ? &pucUncommitted[LOG_RFL_NEXT_SERIAL_NUM] : NULL);
printTableRowEnd();
// LOG_INC_BACKUP_SERIAL_NUM
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_INC_BACKUP_SERIAL_NUM);
fnPrintf( m_pHRequest, "<td>Incremental backup serial number</td>");
printSerialNum( pucLastCommitted ? &pucLastCommitted[LOG_INC_BACKUP_SERIAL_NUM] : NULL);
printSerialNum( pucCheckpoint ? &pucCheckpoint[LOG_INC_BACKUP_SERIAL_NUM] : NULL);
printSerialNum( pucUncommitted ? &pucUncommitted[LOG_INC_BACKUP_SERIAL_NUM] : NULL);
printTableRowEnd();
// LOG_MAX_FILE_SIZE
printTableRowStart( bHighlight = !bHighlight);
fnPrintf( m_pHRequest, "<td>0x%X</td>", LOG_MAX_FILE_SIZE);
fnPrintf( m_pHRequest, "<td>Maximum file size (64K units)</td>");
printLogFileEntryUW( pucLastCommitted, LOG_MAX_FILE_SIZE);
printLogFileEntryUW( pucCheckpoint, LOG_MAX_FILE_SIZE);
printLogFileEntryUW( pucUncommitted, LOG_MAX_FILE_SIZE);
printTableRowEnd();
printTableEnd();
}
/*******************************************************************
Desc:
********************************************************************/
void F_WebPage::printSerialNum(
FLMBYTE * pucSerialNum)
{
if (pucSerialNum)
{
printTableDataStart( FALSE, JUSTIFY_LEFT);
// fnPrintf( m_pHRequest, "0x");
for (int iLoop = 0; iLoop < F_SERIAL_NUM_SIZE; iLoop++)
{
fnPrintf( m_pHRequest, "%02X ", pucSerialNum[iLoop]);
}
printTableDataEnd();
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as unsigned 4 digit hex minimum.
********************************************************************/
void F_WebPage::printLogFileEntryUDX(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
fnPrintf( m_pHRequest, "<td>0x%04X</td>", FB2UD( &pucLog[uiOffset]));
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as unsigned decimal hex in parenthesis.
********************************************************************/
void F_WebPage::printLogFileEntryUD_X(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
printTableDataStart( TRUE, JUSTIFY_LEFT);
printCommaNumText( (FLMUINT64) FB2UD( &pucLog[uiOffset]));
fnPrintf( m_pHRequest, " (0x%X)", FB2UD( &pucLog[uiOffset]));
printTableDataEnd();
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as unsigned decimal.
********************************************************************/
void F_WebPage::printLogFileEntryUD(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
printCommaNum( (FLMUINT64) FB2UD( &pucLog[uiOffset]), JUSTIFY_LEFT);
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as unsigned word.
********************************************************************/
void F_WebPage::printLogFileEntryUW(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
printCommaNum( (FLMUINT64) FB2UW( &pucLog[uiOffset]), JUSTIFY_LEFT);
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as unsigned char.
********************************************************************/
void F_WebPage::printLogFileEntryUC(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
fnPrintf( m_pHRequest, "<td>%u</td>", (unsigned char) pucLog[uiOffset]);
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}
/*******************************************************************
Desc: Print a table entry as yes or no (FLMBOOL)
********************************************************************/
void F_WebPage::printLogFileEntryBool(
FLMBYTE * pucLog,
FLMUINT uiOffset)
{
if (pucLog)
{
printTableDataStart( TRUE, JUSTIFY_LEFT);
printYesNo( (FLMBOOL) pucLog[uiOffset]);
printTableDataEnd();
}
else
{
fnPrintf( m_pHRequest, "<td>-</td>");
}
}