git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
408 lines
8.4 KiB
C++
408 lines
8.4 KiB
C++
//-------------------------------------------------------------------------
|
|
// Desc: Dictionary access routiones.
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 1995-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: fdict.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
|
|
/***************************************************************************
|
|
Desc: Get the field information. Try shared first and then local.
|
|
****************************************************************************/
|
|
RCODE fdictGetField(
|
|
FDICT * pDict,
|
|
FLMUINT uiFieldNum, // [in] Field Number to look up
|
|
FLMUINT * puiFieldType, // [out] Optional
|
|
IFD ** ppFirstIfd, // [out] Optional
|
|
FLMUINT * puiFieldState) // [out] Optional
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
ITT nonstandardItt;
|
|
ITT * pItt;
|
|
|
|
if( pDict && pDict->pIttTbl && uiFieldNum < pDict->uiIttCnt)
|
|
{
|
|
pItt = &pDict->pIttTbl[ uiFieldNum];
|
|
|
|
// Is it really a field?
|
|
|
|
if( ! ITT_IS_FIELD( pItt))
|
|
{
|
|
rc = RC_SET( FERR_BAD_FIELD_NUM);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check if the field is a FLAIM dictionary field.
|
|
// Most of these fields are TEXT fields.
|
|
|
|
if( (uiFieldNum >= FLM_DICT_FIELD_NUMS)
|
|
&& (uiFieldNum <= FLM_LAST_DICT_FIELD_NUM))
|
|
{
|
|
// Most of the dictionary fields are text type.
|
|
// KYBUILD now doesn't verify unregistered or dictionary fields types.
|
|
|
|
pItt = &nonstandardItt;
|
|
nonstandardItt.uiType = FLM_TEXT_TYPE;
|
|
nonstandardItt.pvItem = NULL;
|
|
}
|
|
else if( uiFieldNum >= FLM_UNREGISTERED_TAGS)
|
|
{
|
|
pItt = &nonstandardItt;
|
|
nonstandardItt.uiType = FLM_TEXT_TYPE;
|
|
nonstandardItt.pvItem = NULL;
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET( FERR_BAD_FIELD_NUM);
|
|
goto Exit;
|
|
}
|
|
|
|
}
|
|
if( puiFieldType)
|
|
{
|
|
*puiFieldType = ITT_FLD_GET_TYPE( pItt);
|
|
}
|
|
if( ppFirstIfd)
|
|
{
|
|
*ppFirstIfd = (IFD *)pItt->pvItem;
|
|
}
|
|
if( puiFieldState)
|
|
{
|
|
*puiFieldState = ITT_FLD_GET_STATE( pItt);
|
|
}
|
|
|
|
Exit:
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Get the encryption information.
|
|
****************************************************************************/
|
|
RCODE fdictGetEncInfo(
|
|
FDB * pDb,
|
|
FLMUINT uiEncId, // [in] Encryption definition to look up
|
|
FLMUINT * puiEncType, // [out] Optional
|
|
FLMUINT * puiEncState // [out] Optional
|
|
)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
ITT * pItt;
|
|
FDICT * pDict = pDb->pDict;
|
|
FlmRecord * pRecord = NULL;
|
|
void * pvField = NULL;
|
|
FLMUINT uiEncState;
|
|
FLMUINT uiEncType;
|
|
|
|
if ( pDb->pFile->bInLimitedMode)
|
|
{
|
|
flmAssert( 0);
|
|
rc = RC_SET( FERR_ENCRYPTION_UNAVAILABLE);
|
|
goto Exit;
|
|
}
|
|
|
|
if( pDict && pDict->pIttTbl && uiEncId < pDict->uiIttCnt)
|
|
{
|
|
pItt = &pDict->pIttTbl[ uiEncId];
|
|
|
|
// Is it really an encryption definition?
|
|
|
|
if( ! ITT_IS_ENCDEF( pItt))
|
|
{
|
|
rc = RC_SET( FERR_BAD_ENCDEF_ID);
|
|
goto Exit;
|
|
}
|
|
|
|
uiEncType = ((F_CCS *)pItt->pvItem)->getEncType();
|
|
|
|
// Get the Encryption record and determine the state.
|
|
if (RC_BAD( rc = FlmRecordRetrieve( (HFDB)pDb,
|
|
FLM_DICT_CONTAINER,
|
|
uiEncId,
|
|
FO_EXACT,
|
|
&pRecord,
|
|
NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pvField = pRecord->find( pRecord->root(),
|
|
FLM_STATE_TAG);
|
|
if (pvField)
|
|
{
|
|
const char * pDataPtr = (const char *)pRecord->getDataPtr( pvField);
|
|
|
|
if (f_strnicmp( pDataPtr, "chec", 4) == 0)
|
|
{
|
|
uiEncState = ITT_ENC_STATE_CHECKING;
|
|
}
|
|
else if (f_strnicmp( pDataPtr, "purg", 4) == 0)
|
|
{
|
|
uiEncState = ITT_ENC_STATE_PURGE;
|
|
}
|
|
else if (f_strnicmp( pDataPtr, "acti", 4) == 0)
|
|
{
|
|
uiEncState = ITT_ENC_STATE_ACTIVE;
|
|
}
|
|
else
|
|
{
|
|
uiEncState = ITT_ENC_STATE_UNUSED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uiEncState = ITT_ENC_STATE_UNUSED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET( FERR_BAD_ENCDEF_ID);
|
|
goto Exit;
|
|
}
|
|
|
|
if( puiEncType)
|
|
{
|
|
*puiEncType = uiEncType;
|
|
}
|
|
if( puiEncState)
|
|
{
|
|
*puiEncState = uiEncState;
|
|
}
|
|
|
|
Exit:
|
|
|
|
if (pRecord)
|
|
{
|
|
pRecord->Release();
|
|
}
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Get the Container given a container number.
|
|
****************************************************************************/
|
|
RCODE fdictGetContainer(
|
|
FDICT * pDict,
|
|
FLMUINT uiContNum,
|
|
LFILE ** ppLFile)
|
|
{
|
|
ITT * pItt;
|
|
|
|
if( pDict && uiContNum < pDict->uiIttCnt && pDict->pIttTbl)
|
|
{
|
|
pItt = &pDict->pIttTbl[ uiContNum];
|
|
|
|
// Is it really a container?
|
|
|
|
if( !ITT_IS_CONTAINER( pItt))
|
|
{
|
|
return( RC_SET( FERR_BAD_CONTAINER));
|
|
}
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = (LFILE *) pItt->pvItem;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Hard coded container - data is [0], dictionary is [1].
|
|
|
|
if( uiContNum == FLM_DATA_CONTAINER)
|
|
{
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = &pDict->pLFileTbl[ LFILE_DATA_CONTAINER_OFFSET];
|
|
}
|
|
}
|
|
else if( uiContNum == FLM_DICT_CONTAINER)
|
|
{
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = &pDict->pLFileTbl[ LFILE_DICT_CONTAINER_OFFSET];
|
|
}
|
|
}
|
|
else if( uiContNum == FLM_TRACKER_CONTAINER)
|
|
{
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = &pDict->pLFileTbl[ LFILE_TRACKER_CONTAINER_OFFSET];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return( RC_SET( FERR_BAD_CONTAINER));
|
|
}
|
|
}
|
|
|
|
return( FERR_OK);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Get the IXD, LFILE and IFD information given an index number.
|
|
****************************************************************************/
|
|
RCODE fdictGetIndex(
|
|
FDICT * pDict,
|
|
FLMBOOL bInLimitedMode,
|
|
FLMUINT uiIxNum,
|
|
LFILE ** ppLFile, // [out] optional
|
|
IXD ** ppIxd, // [out] optional
|
|
FLMBOOL bOfflineOk)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
ITT * pItt;
|
|
LFILE * pLFile;
|
|
IXD * pIxd;
|
|
|
|
if( ppIxd)
|
|
{
|
|
*ppIxd = NULL;
|
|
}
|
|
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = NULL;
|
|
}
|
|
|
|
if( pDict && uiIxNum < pDict->uiIttCnt && pDict->pIttTbl)
|
|
{
|
|
pItt = &pDict->pIttTbl[ uiIxNum];
|
|
|
|
// Is it really a container?
|
|
|
|
if( !ITT_IS_INDEX( pItt))
|
|
{
|
|
rc = RC_SET( FERR_BAD_IX);
|
|
goto Exit;
|
|
}
|
|
pLFile = (LFILE *) pItt->pvItem;
|
|
pIxd = pLFile->pIxd;
|
|
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = pLFile;
|
|
}
|
|
|
|
if( ppIxd)
|
|
{
|
|
*ppIxd = pIxd;
|
|
}
|
|
|
|
// If the index is suspended the IXD_OFFLINE flag
|
|
// will be set, so it is sufficient to just test
|
|
// the IXD_OFFLINE for both suspended and offline
|
|
// conditions.
|
|
|
|
if( (pIxd->uiFlags & IXD_OFFLINE) && !bOfflineOk)
|
|
{
|
|
rc = RC_SET( FERR_INDEX_OFFLINE);
|
|
goto Exit;
|
|
}
|
|
|
|
// An encrypted index that cannot be decrypted is as good as
|
|
// offline.
|
|
if ( pIxd->uiEncId && bInLimitedMode && !bOfflineOk)
|
|
{
|
|
rc = RC_SET( FERR_INDEX_OFFLINE);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if (uiIxNum == FLM_DICT_INDEX)
|
|
{
|
|
pLFile = pDict->pLFileTbl + LFILE_DICT_INDEX_OFFSET;
|
|
if( ppLFile)
|
|
{
|
|
*ppLFile = pLFile;
|
|
}
|
|
if( ppIxd)
|
|
{
|
|
*ppIxd = pLFile->pIxd;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET( FERR_BAD_IX);
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Given a IXD ID (index drn), returns the next Index Def (IXD).
|
|
****************************************************************************/
|
|
RCODE fdictGetNextIXD(
|
|
FDICT * pDict,
|
|
FLMUINT uiIndexNum,
|
|
IXD ** ppIxd)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
IXD * pIxd = NULL;
|
|
|
|
flmAssert( pDict && pDict->uiIxdCnt);
|
|
|
|
for( uiIndexNum++; uiIndexNum < pDict->uiIttCnt; uiIndexNum++)
|
|
{
|
|
ITT * pItt = &pDict->pIttTbl[ uiIndexNum];
|
|
if( ITT_IS_INDEX( pItt))
|
|
{
|
|
LFILE * pLFile = (LFILE *) pItt->pvItem;
|
|
pIxd = pLFile->pIxd;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !pIxd && uiIndexNum < FLM_DICT_INDEX)
|
|
{
|
|
// Special case -- return the dictionary index
|
|
pIxd = pDict->pIxdTbl;
|
|
}
|
|
|
|
if( pIxd)
|
|
{
|
|
// Check to see if the index is offline. Still return *ppIxd.
|
|
|
|
if( pIxd->uiFlags & IXD_OFFLINE)
|
|
{
|
|
rc = RC_SET( FERR_INDEX_OFFLINE);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET( FERR_EOF_HIT);
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
// Always set the return parm.
|
|
|
|
if( ppIxd)
|
|
{
|
|
*ppIxd = pIxd;
|
|
}
|
|
|
|
return( rc);
|
|
}
|