//-------------------------------------------------------------------------
// 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 /* see also FLMHTTP.h */
#define FLM_SESSION_ID_NAME "flmsessionid"
/****************************************************************************
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, "\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 == '=')
{
pszTemp++; // skip past the equal sign
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
FLM_TIMER_UNITS_TO_MILLI(uiTimerUnits, uiMilli);
//Determine the number of days
uiDays = uiMilli / 86400000;
uiTemp = uiMilli % 86400000; // Get the remainder
//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, "\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,
"
"
""
"%s\n",
m_pszURLString, pszURL, pszTitle);
printStyle();
fnPrintf( m_pHRequest, "\n\n");
f_sprintf( (char *)szTemp,
"Stop Auto-refresh", m_pszURLString, pszURL);
}
else
{
fnPrintf( m_pHRequest, "%s\n", pszTitle);
printStyle();
fnPrintf( m_pHRequest, "\n\n");
f_sprintf( (char *)szTemp,
"Start Auto-refresh (5 sec.)",
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, "Refresh, ", 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, "\n");
fnPrintf( m_pHRequest, "\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, (size_t *)&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,
"\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, "