git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
401 lines
9.9 KiB
C++
401 lines
9.9 KiB
C++
//-------------------------------------------------------------------------
|
|
// Desc: HTML callback function for displaying monitoring web pages.
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 2001-2003,2005-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: flmimon.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
|
|
FSTATIC char * tokenizer(
|
|
const char * pszString,
|
|
FLMBYTE ucToken1,
|
|
FLMBYTE ucToken2);
|
|
|
|
F_WebPageFactory * gv_pWPFact = NULL;
|
|
|
|
/****************************************************************************
|
|
Desc: This is the function that the HTTP server calls when it wants to
|
|
display one of our pages
|
|
****************************************************************************/
|
|
int flmHttpCallback(
|
|
HRequest * pHRequest,
|
|
void * //pvUserData
|
|
)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
F_WebPage * pPage = NULL;
|
|
char * pszPath = NULL;
|
|
char * pszQuery = NULL;
|
|
char * pszTemp = NULL;
|
|
const char * pszConstTemp = NULL;
|
|
#define MAX_PARAMS 10
|
|
const char * pszParams[ MAX_PARAMS];
|
|
FLMUINT uiNumParams;
|
|
|
|
// If we get a NULL for the pHRequest object, then we are shutting down...
|
|
|
|
if (pHRequest == NULL)
|
|
{
|
|
// Remove the globals that enable the secure pages...
|
|
gv_FlmSysData.HttpConfigParms.fnSetGblValue(
|
|
FLM_SECURE_PASSWORD, "", 0);
|
|
gv_FlmSysData.HttpConfigParms.fnSetGblValue(
|
|
FLM_SECURE_EXPIRATION, "", 0);
|
|
|
|
// Delete the web page factory object
|
|
if (gv_pWPFact)
|
|
{
|
|
gv_pWPFact->Release( NULL);
|
|
}
|
|
gv_pWPFact = NULL;
|
|
goto Exit;
|
|
}
|
|
|
|
// Increment the use count (helps ensure that the function pointers
|
|
// that display() references don't go away while display() still needs
|
|
// them.
|
|
|
|
f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
gv_FlmSysData.HttpConfigParms.uiUseCount++;
|
|
f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
|
|
// Must not access any HRequest function pointers prior to incrementing the
|
|
// use count.
|
|
|
|
if( !gv_FlmSysData.HttpConfigParms.fnReqPath)
|
|
{
|
|
flmAssert( 0);
|
|
rc = RC_SET( FERR_FAILURE);
|
|
goto Exit;
|
|
}
|
|
|
|
// If the web page factory does not exist yet, then we need to create it.
|
|
if (!gv_pWPFact)
|
|
{
|
|
f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
// In the time it took us to get the lock, some other thread might
|
|
// have come along and created the factory already...
|
|
if (!gv_pWPFact)
|
|
{
|
|
if ((gv_pWPFact = f_new F_WebPageFactory) == NULL)
|
|
{
|
|
rc = RC_SET( FERR_MEM);
|
|
f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
goto Exit;
|
|
}
|
|
}
|
|
f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
}
|
|
|
|
pszConstTemp = gv_FlmSysData.HttpConfigParms.fnReqPath( pHRequest);
|
|
flmAssert( pszConstTemp);
|
|
|
|
if( RC_BAD( rc = f_alloc(
|
|
f_strlen( pszConstTemp) + 1, &pszPath)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
f_strcpy( pszPath, pszConstTemp);
|
|
|
|
pszConstTemp = gv_FlmSysData.HttpConfigParms.fnReqQuery( pHRequest);
|
|
if( pszConstTemp)
|
|
{
|
|
if( RC_BAD( rc = f_alloc( f_strlen( pszConstTemp) + 1, &pszQuery)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
f_strcpy( pszQuery, pszConstTemp);
|
|
pszConstTemp = pszQuery;
|
|
}
|
|
else // This URL had no query string...
|
|
{
|
|
// If pszQuery is NULL, it causes problems further down, so we'll
|
|
// make it a pointer to a null string...
|
|
|
|
if( RC_BAD( rc = f_alloc( 1, &pszQuery)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
pszQuery[0] = '\0';
|
|
}
|
|
|
|
// Strip off pszURLString (and the next '/', if there is one) from the request and store
|
|
// what's left as pszParams[0].
|
|
// (ie: /coredb/FlmSysData --> FlmSysData)
|
|
|
|
// Note: The reason we're checking for the URL string first is because if
|
|
// we're using our own http stack, then this callback is called for every
|
|
// http request and we don't want to crash if we've got a short URI.
|
|
// When we're running under DS, we're guarenteed that the URLString will
|
|
// be part of the URI.
|
|
|
|
if( f_strlen( pszPath) >= gv_FlmSysData.HttpConfigParms.uiURLStringLen)
|
|
{
|
|
pszConstTemp = pszPath + gv_FlmSysData.HttpConfigParms.uiURLStringLen;
|
|
if( *pszConstTemp == '/')
|
|
{
|
|
pszConstTemp++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszConstTemp = pszPath;
|
|
}
|
|
|
|
pszParams[0] = pszConstTemp;
|
|
uiNumParams = 1;
|
|
|
|
|
|
// Parse parameters in the query string
|
|
// Note that it's technically incorrect to have more than one ? in a
|
|
// URL, but we didn't know that when we first started creating some of
|
|
// these pages and as a result, some queries are in the form of:
|
|
// ?name1=value1?name2=value2?name3=value3... (which is improper) and
|
|
// some have the form:
|
|
// ?name1=value1&name2=value2&name3=value3... (which is correct).
|
|
|
|
pszTemp = pszQuery;
|
|
|
|
while( *pszTemp != 0)
|
|
{
|
|
flmAssert( uiNumParams < MAX_PARAMS);
|
|
pszParams[ uiNumParams] = pszTemp;
|
|
uiNumParams++;
|
|
|
|
pszTemp = tokenizer( pszTemp, '?', '&');
|
|
|
|
if (*pszTemp)
|
|
{
|
|
*pszTemp = '\0';
|
|
pszTemp++;
|
|
}
|
|
}
|
|
|
|
// Tell the factory to create the page
|
|
|
|
if (RC_BAD( rc = gv_pWPFact->create( pszParams[0], &pPage, pHRequest)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
pPage->setMembers( pHRequest);
|
|
|
|
// display the page
|
|
if( RC_BAD( rc = pPage->display (uiNumParams, &pszParams[0])))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
// Decrement the use count
|
|
|
|
if( pHRequest)
|
|
{
|
|
f_mutexLock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
if( gv_FlmSysData.HttpConfigParms.uiUseCount > 0)
|
|
{
|
|
gv_FlmSysData.HttpConfigParms.uiUseCount--;
|
|
}
|
|
else
|
|
{
|
|
flmAssert( 0);
|
|
}
|
|
f_mutexUnlock( gv_FlmSysData.HttpConfigParms.hMutex);
|
|
}
|
|
|
|
if (pPage)
|
|
{
|
|
gv_pWPFact->Release( &pPage);
|
|
}
|
|
|
|
if (pszPath)
|
|
{
|
|
f_free( &pszPath);
|
|
}
|
|
|
|
if (pszQuery)
|
|
{
|
|
f_free( &pszQuery);
|
|
}
|
|
|
|
return (int)rc;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Given a string, returns a pointer to the next occurance of either
|
|
of two specific characters.
|
|
****************************************************************************/
|
|
FSTATIC char * tokenizer(
|
|
const char * pszString,
|
|
FLMBYTE ucToken1,
|
|
FLMBYTE ucToken2)
|
|
{
|
|
while (*pszString != ucToken1 && *pszString != ucToken2 && *pszString != 0)
|
|
{
|
|
pszString++;
|
|
}
|
|
|
|
return( (char *)pszString);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Given two address, calculates the difference between them and
|
|
converts them to a string in hex (including the 0x).
|
|
This is in its own function because of some possible issues
|
|
with win64 and maybe other 64bit OS's
|
|
****************************************************************************/
|
|
void printOffset(
|
|
void * pBase,
|
|
void * pAddress,
|
|
char * pszOffset)
|
|
{
|
|
FLMUINT uiBase = (FLMUINT)pBase;
|
|
FLMUINT uiAddress = (FLMUINT)pAddress;
|
|
|
|
f_sprintf( pszOffset, "0x%lX", (FLMUINT)(uiAddress - uiBase));
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Takes a pointer and converts its address to a string in hex
|
|
(including the 0x). This is in its own function because of some
|
|
possible issues with win64 and maybe other 64bit OS's
|
|
****************************************************************************/
|
|
void printAddress(
|
|
void * pAddress,
|
|
char * pszBuff)
|
|
{
|
|
FLMUINT64 ui64Addr = (FLMUINT64)((FLMUINT)pAddress);
|
|
FLMUINT uiHigh = (FLMUINT)(ui64Addr >> 32);
|
|
FLMUINT uiLow = (FLMUINT)(ui64Addr & (FLMUINT64)0xFFFFFFFF);
|
|
|
|
if( uiHigh)
|
|
{
|
|
f_sprintf( pszBuff, "0x%X%08X",
|
|
(unsigned)uiHigh, (unsigned)uiLow);
|
|
}
|
|
else
|
|
{
|
|
f_sprintf( pszBuff, "0x%X", (unsigned)uiLow);
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
Desc: Implements the addChar function of the DynamicBuffer class
|
|
*******************************************************************/
|
|
RCODE F_DynamicBuffer::addChar(
|
|
char ucCharacter)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
|
|
if (!m_bSetup)
|
|
{
|
|
flmAssert( 0);
|
|
rc = RC_SET( FERR_FAILURE);
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
f_mutexLock( m_hMutex);
|
|
|
|
// Is there room for just one more character plus a terminator?
|
|
if ((m_uiBuffSize - m_uiUsedChars) > 1)
|
|
{
|
|
m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
|
|
m_pucBuffer[ m_uiUsedChars] = 0;
|
|
}
|
|
else
|
|
{
|
|
// Allocate a new buffer or increase the size of the existing one.
|
|
if( !m_uiBuffSize)
|
|
{
|
|
if( RC_BAD( rc = f_alloc( 50, &m_pucBuffer)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
m_uiBuffSize = 50;
|
|
}
|
|
else
|
|
{
|
|
if( RC_BAD( rc = f_realloc( m_uiBuffSize + 50, &m_pucBuffer)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
m_uiBuffSize += 50;
|
|
}
|
|
|
|
|
|
m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
|
|
m_pucBuffer[ m_uiUsedChars] = 0;
|
|
}
|
|
|
|
Exit:
|
|
|
|
if ( m_bSetup)
|
|
{
|
|
f_mutexUnlock( m_hMutex);
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/******************************************************************
|
|
Desc: Implements the addChar function of the DynamicBuffer class
|
|
*******************************************************************/
|
|
RCODE F_DynamicBuffer::addString( const char * pszString)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
const char * pTemp = pszString;
|
|
FLMUINT uiTmpPos = m_uiUsedChars;
|
|
|
|
|
|
while( *pTemp)
|
|
{
|
|
if (RC_BAD( rc = addChar( *pTemp)))
|
|
{
|
|
// Reset the buffer to its state prior to this call.
|
|
|
|
m_uiUsedChars = uiTmpPos;
|
|
if (m_uiBuffSize > 0)
|
|
{
|
|
m_pucBuffer[ m_uiUsedChars] = 0;
|
|
}
|
|
goto Exit;
|
|
}
|
|
pTemp++;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/******************************************************************
|
|
Desc: Implements the addChar function of the DynamicBuffer class
|
|
*******************************************************************/
|
|
const char * F_DynamicBuffer::printBuffer()
|
|
{
|
|
return( (const char *)m_pucBuffer);
|
|
}
|