#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <mach/mach_time.h> // for dsTimeStamp
#include "CLog.h"
#include "CNodeList.h"
#include "CRefTable.h"
#include "CServerPlugin.h"
#include "CString.h"
#include "DSCThread.h"
#include "PrivateTypes.h"
#include "DSUtils.h"
#include "CPlugInList.h"
#include "ServerControl.h"
extern CPlugInList *gPlugins;
CNodeList::CNodeList ( void )
{
fTreePtr = nil;
fCount = 0;
fNodeChangeToken = 1001; fLocalNode = nil;
fAuthenticationSearchNode = nil;
fContactsSearchNode = nil;
fNetworkSearchNode = nil;
fConfigureNode = nil;
fLocalHostedNodes = nil;
fDefaultNetworkNodes = nil;
bDHCPLDAPv3InitComplete = false;
}
CNodeList::~CNodeList ( void )
{
this->DeleteTree( &fTreePtr );
fTreePtr = nil;
if ( fLocalNode != nil )
{
if ( fLocalNode->fNodeName != nil )
{
free( fLocalNode->fNodeName );
}
free( fLocalNode );
fLocalNode = nil;
}
if ( fAuthenticationSearchNode != nil )
{
if ( fAuthenticationSearchNode->fNodeName != nil )
{
free( fAuthenticationSearchNode->fNodeName );
}
free( fAuthenticationSearchNode );
fAuthenticationSearchNode = nil;
}
if ( fContactsSearchNode != nil )
{
if ( fContactsSearchNode->fNodeName != nil )
{
free( fContactsSearchNode->fNodeName );
}
free( fContactsSearchNode );
fContactsSearchNode = nil;
}
if ( fNetworkSearchNode != nil )
{
if ( fNetworkSearchNode->fNodeName != nil )
{
free( fNetworkSearchNode->fNodeName );
}
free( fNetworkSearchNode );
fNetworkSearchNode = nil;
}
if ( fConfigureNode != nil )
{
if ( fConfigureNode->fNodeName != nil )
{
free( fConfigureNode->fNodeName );
}
free( fConfigureNode );
fConfigureNode = nil;
}
if ( fLocalHostedNodes != nil )
{
this->DeleteTree( &fLocalHostedNodes );
fLocalHostedNodes = nil;
}
if ( fDefaultNetworkNodes != nil )
{
this->DeleteTree( &fDefaultNetworkNodes );
fDefaultNetworkNodes = nil;
}
}
sInt32 CNodeList::DeleteTree ( sTreeNode **inTree )
{
fMutex.Wait();
try
{
if ( *inTree != nil )
{
this->DeleteTree( &((*inTree)->left) );
this->DeleteTree( &((*inTree)->right) );
if ( (*inTree)->fDataListPtr != nil )
{
::dsDataListDeallocatePriv( (*inTree)->fDataListPtr );
free( (*inTree)->fDataListPtr );
(*inTree)->fDataListPtr = nil;
}
delete( *inTree );
}
*inTree = nil;
}
catch( sInt32 err )
{
}
fMutex.Signal();
return( 1 );
}
sInt32 CNodeList::AddNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 0;
fMutex.Wait();
try
{
switch(inType)
{
case kLocalHostedType:
siResult = AddNodeToTree( &fLocalHostedNodes, inNodeName, inListPtr, inType, inPlugInPtr, inToken );
break;
case kDefaultNetworkNodeType:
siResult = AddNodeToTree( &fDefaultNetworkNodes, inNodeName, inListPtr, inType, inPlugInPtr, inToken );
break;
case kSearchNodeType:
if (fAuthenticationSearchNode == nil)
{
siResult = AddAuthenticationSearchNode( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Attempt to register second Authentication Search Node failed." );
}
break;
case kContactsSearchNodeType:
if (fContactsSearchNode == nil)
{
siResult = AddContactsSearchNode( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Attempt to register second Contacts Search Node failed." );
}
break;
case kNetworkSearchNodeType:
if (fNetworkSearchNode == nil)
{
siResult = AddNetworkSearchNode( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Attempt to register second Network Search Node failed." );
}
break;
case kConfigNodeType:
if (fConfigureNode == nil)
{
siResult = AddConfigureNode( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Attempt to register second Configure Node failed." );
}
break;
case kLocalNodeType:
if (fLocalNode == nil)
{
siResult = AddLocalNode( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Attempt to register second Local Node failed." );
}
break;
case kDHCPLDAPv3NodeType:
if ( !bDHCPLDAPv3InitComplete )
{
siResult = AddDHCPLDAPv3Node( inNodeName, inListPtr, inType, inPlugInPtr, inToken );
}
else
{
DBGLOG( kLogApplication, "Duplicate attempt to indicate DHCP LDAPv3 initialization has failed." );
}
break;
case kDirNodeType:
siResult = AddNodeToTree( &fTreePtr, inNodeName, inListPtr, inType, inPlugInPtr, inToken );
fCount++;
fNodeChangeToken++;
gSrvrCntl->NotifyDirNodeAdded(inNodeName);
break;
default:
break;
} }
catch( sInt32 err )
{
siResult = err;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList::AddLocalNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *aLocalNode = nil;
if ( fLocalNode != nil )
{
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
return( 0 );
}
fMutex.Wait();
try
{
aLocalNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( aLocalNode == nil ) throw((sInt32)eMemoryAllocError);
aLocalNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( aLocalNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( aLocalNode->fNodeName, inNodeName );
aLocalNode->fDataListPtr = inListPtr;
aLocalNode->fPlugInPtr = inPlugInPtr;
aLocalNode->fPlugInToken = inToken;
aLocalNode->fType = inType;
aLocalNode->left = nil;
aLocalNode->right = nil;
fLocalNode = aLocalNode;
}
catch( sInt32 err )
{
if ( aLocalNode != nil )
{
if (aLocalNode->fNodeName != nil)
{
free(aLocalNode->fNodeName);
aLocalNode->fNodeName = nil;
}
if (aLocalNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( aLocalNode->fDataListPtr );
free ( aLocalNode->fDataListPtr );
aLocalNode->fDataListPtr = nil;
}
free( aLocalNode );
aLocalNode = nil;
fLocalNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList:: AddAuthenticationSearchNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *anAuthenticationSearchNode = nil;
if ( fAuthenticationSearchNode != nil )
{
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
return( 0 );
}
fMutex.Wait();
try
{
anAuthenticationSearchNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( anAuthenticationSearchNode == nil ) throw((sInt32)eMemoryAllocError);
anAuthenticationSearchNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( anAuthenticationSearchNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( anAuthenticationSearchNode->fNodeName, inNodeName );
anAuthenticationSearchNode->fDataListPtr = inListPtr;
anAuthenticationSearchNode->fPlugInPtr = inPlugInPtr;
anAuthenticationSearchNode->fPlugInToken = inToken;
anAuthenticationSearchNode->fType = inType;
anAuthenticationSearchNode->left = nil;
anAuthenticationSearchNode->right = nil;
fAuthenticationSearchNode = anAuthenticationSearchNode;
}
catch( sInt32 err )
{
if ( anAuthenticationSearchNode != nil )
{
if (anAuthenticationSearchNode->fNodeName != nil)
{
free(anAuthenticationSearchNode->fNodeName);
anAuthenticationSearchNode->fNodeName = nil;
}
if (anAuthenticationSearchNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( anAuthenticationSearchNode->fDataListPtr );
free ( anAuthenticationSearchNode->fDataListPtr );
anAuthenticationSearchNode->fDataListPtr = nil;
}
free( anAuthenticationSearchNode );
anAuthenticationSearchNode = nil;
fAuthenticationSearchNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList:: AddContactsSearchNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *aContactsSearchNode = nil;
if ( fContactsSearchNode != nil )
{
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
return( 0 );
}
fMutex.Wait();
try
{
aContactsSearchNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( aContactsSearchNode == nil ) throw((sInt32)eMemoryAllocError);
aContactsSearchNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( aContactsSearchNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( aContactsSearchNode->fNodeName, inNodeName );
aContactsSearchNode->fDataListPtr = inListPtr;
aContactsSearchNode->fPlugInPtr = inPlugInPtr;
aContactsSearchNode->fPlugInToken = inToken;
aContactsSearchNode->fType = inType;
aContactsSearchNode->left = nil;
aContactsSearchNode->right = nil;
fContactsSearchNode = aContactsSearchNode;
}
catch( sInt32 err )
{
if ( aContactsSearchNode != nil )
{
if (aContactsSearchNode->fNodeName != nil)
{
free(aContactsSearchNode->fNodeName);
aContactsSearchNode->fNodeName = nil;
}
if (aContactsSearchNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( aContactsSearchNode->fDataListPtr );
free ( aContactsSearchNode->fDataListPtr );
aContactsSearchNode->fDataListPtr = nil;
}
free( aContactsSearchNode );
aContactsSearchNode = nil;
fContactsSearchNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList:: AddNetworkSearchNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *aNetworkSearchNode = nil;
if ( fNetworkSearchNode != nil )
{
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
return( 0 );
}
fMutex.Wait();
try
{
aNetworkSearchNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( aNetworkSearchNode == nil ) throw((sInt32)eMemoryAllocError);
aNetworkSearchNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( aNetworkSearchNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( aNetworkSearchNode->fNodeName, inNodeName );
aNetworkSearchNode->fDataListPtr = inListPtr;
aNetworkSearchNode->fPlugInPtr = inPlugInPtr;
aNetworkSearchNode->fPlugInToken = inToken;
aNetworkSearchNode->fType = inType;
aNetworkSearchNode->left = nil;
aNetworkSearchNode->right = nil;
fNetworkSearchNode = aNetworkSearchNode;
}
catch( sInt32 err )
{
if ( aNetworkSearchNode != nil )
{
if (aNetworkSearchNode->fNodeName != nil)
{
free(aNetworkSearchNode->fNodeName);
aNetworkSearchNode->fNodeName = nil;
}
if (aNetworkSearchNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( aNetworkSearchNode->fDataListPtr );
free ( aNetworkSearchNode->fDataListPtr );
aNetworkSearchNode->fDataListPtr = nil;
}
free( aNetworkSearchNode );
aNetworkSearchNode = nil;
fNetworkSearchNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList:: AddConfigureNode ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *aConfigureNode = nil;
if ( fConfigureNode != nil )
{
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
return( 0 );
}
fMutex.Wait();
try
{
aConfigureNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( aConfigureNode == nil ) throw((sInt32)eMemoryAllocError);
aConfigureNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( aConfigureNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( aConfigureNode->fNodeName, inNodeName );
aConfigureNode->fDataListPtr = inListPtr;
aConfigureNode->fPlugInPtr = inPlugInPtr;
aConfigureNode->fPlugInToken = inToken;
aConfigureNode->fType = inType;
aConfigureNode->left = nil;
aConfigureNode->right = nil;
fConfigureNode = aConfigureNode;
}
catch( sInt32 err )
{
if ( aConfigureNode != nil )
{
if (aConfigureNode->fNodeName != nil)
{
free(aConfigureNode->fNodeName);
aConfigureNode->fNodeName = nil;
}
if (aConfigureNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( aConfigureNode->fDataListPtr );
free ( aConfigureNode->fDataListPtr );
aConfigureNode->fDataListPtr = nil;
}
free( aConfigureNode );
aConfigureNode = nil;
fConfigureNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList::AddDHCPLDAPv3Node ( const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
bDHCPLDAPv3InitComplete = true;
return( eDSNoErr );
}
sInt32 CNodeList:: AddNodeToTree ( sTreeNode **inTree,
const char *inNodeName,
tDataList *inListPtr,
eDirNodeType inType,
CServerPlugin *inPlugInPtr,
uInt32 inToken )
{
sInt32 siResult = 1;
sTreeNode *current = nil;
sTreeNode *parent = nil;
sTreeNode *pNewNode = nil;
bool bAddNode = true;
fMutex.Wait();
try
{
current = *inTree;
while ( current != nil )
{
parent = current;
siResult = CompareString( inNodeName, current->fNodeName );
if ( siResult < 0 )
{
current = current->left;
}
else if ( siResult > 0 )
{
current = current->right;
}
else {
current = nil;
if (inListPtr != nil)
{
::dsDataListDeallocatePriv( inListPtr );
free ( inListPtr );
inListPtr = nil;
}
bAddNode = false;
}
}
if (bAddNode)
{
pNewNode = (sTreeNode *)::calloc( 1, sizeof( sTreeNode ) );
if ( pNewNode == nil ) throw((sInt32)eMemoryAllocError);
pNewNode->fNodeName = (char *)::calloc( 1, ::strlen( inNodeName ) + 1 );
if ( pNewNode->fNodeName == nil ) throw((sInt32)eMemoryAllocError);
::strcpy( pNewNode->fNodeName, inNodeName );
pNewNode->fDataListPtr = inListPtr;
pNewNode->fPlugInPtr = inPlugInPtr;
pNewNode->fPlugInToken = inToken;
pNewNode->fType = inType;
pNewNode->left = nil;
pNewNode->right = nil;
if ( parent == nil )
{
*inTree = pNewNode;
siResult = 1;
}
else
{
siResult = CompareString( inNodeName, parent->fNodeName );
if ( siResult < 0 )
{
parent->left = pNewNode;
}
else if ( siResult > 0 )
{
parent->right = pNewNode;
}
}
} }
catch( sInt32 err )
{
if ( pNewNode != nil )
{
if (pNewNode->fNodeName != nil)
{
free(pNewNode->fNodeName);
pNewNode->fNodeName = nil;
}
if (pNewNode->fDataListPtr != nil)
{
::dsDataListDeallocatePriv( pNewNode->fDataListPtr );
free ( pNewNode->fDataListPtr );
pNewNode->fDataListPtr = nil;
}
free( pNewNode );
pNewNode = nil;
}
siResult = 0;
}
fMutex.Signal();
return( siResult );
}
bool CNodeList::GetLocalNode ( CServerPlugin **outPlugInPtr )
{
bool found = false;
fMutex.Wait();
if ( fLocalNode != nil )
{
*outPlugInPtr = GetPluginPtr(fLocalNode);
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetLocalNode ( tDataList **outListPtr )
{
bool found = false;
fMutex.Wait();
if ( fLocalNode != nil )
{
*outListPtr = fLocalNode->fDataListPtr;
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetAuthenticationSearchNode ( CServerPlugin **outPlugInPtr )
{
bool found = false;
fMutex.Wait();
if ( fAuthenticationSearchNode != nil )
{
*outPlugInPtr = GetPluginPtr(fAuthenticationSearchNode);
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetAuthenticationSearchNode ( tDataList **outListPtr )
{
bool found = false;
fMutex.Wait();
if ( fAuthenticationSearchNode != nil )
{
*outListPtr = fAuthenticationSearchNode->fDataListPtr;
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetContactsSearchNode ( CServerPlugin **outPlugInPtr )
{
bool found = false;
fMutex.Wait();
if ( fContactsSearchNode != nil )
{
*outPlugInPtr = GetPluginPtr(fContactsSearchNode);
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetContactsSearchNode ( tDataList **outListPtr )
{
bool found = false;
fMutex.Wait();
if ( fContactsSearchNode != nil )
{
*outListPtr = fContactsSearchNode->fDataListPtr;
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetNetworkSearchNode ( CServerPlugin **outPlugInPtr )
{
bool found = false;
fMutex.Wait();
if ( fNetworkSearchNode != nil )
{
*outPlugInPtr = GetPluginPtr(fNetworkSearchNode);
found = true;
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetNetworkSearchNode ( tDataList **outListPtr )
{
bool found = false;
fMutex.Wait();
if ( fNetworkSearchNode != nil )
{
*outListPtr = fNetworkSearchNode->fDataListPtr;
found = true;
}
fMutex.Signal();
return( found );
}
void CNodeList::RegisterAll ( void )
{
fMutex.Wait();
try
{
this->Register( fTreePtr );
}
catch( sInt32 err )
{
}
fMutex.Signal();
}
void CNodeList::Register ( sTreeNode *inTree )
{
if ( inTree != nil )
{
Register( inTree->left );
Register( inTree->right );
}
}
uInt32 CNodeList::GetNodeCount ( void )
{
return( fCount );
}
uInt32 CNodeList:: GetNodeChangeToken ( void )
{
return( fNodeChangeToken );
}
void CNodeList::CountNodes ( uInt32 *outCount )
{
fMutex.Wait();
try
{
this->Count( fTreePtr, outCount );
}
catch( sInt32 err )
{
}
fMutex.Signal();
}
void CNodeList::Count ( sTreeNode *inTree, uInt32 *outCount )
{
if ( inTree != nil )
{
Count( inTree->left, outCount );
*outCount += 1;
Count( inTree->right, outCount );
}
}
sInt32 CNodeList::GetNodes ( char *inStr,
tDirPatternMatch inMatch,
tDataBuffer *inBuff )
{
sInt32 siResult = eDSNoErr;
sTreeNode *outNodePtr = nil;
if ( (inMatch == eDSLocalNodeNames) && (fLocalNode == nil) )
{
WaitForLocalNode();
}
if ( (inMatch == eDSAuthenticationSearchNodeName) && (fAuthenticationSearchNode == nil) )
{
WaitForLocalNode();
WaitForDHCPLDAPv3Init();
WaitForAuthenticationSearchNode();
}
else if ( (inMatch == eDSContactsSearchNodeName) && (fContactsSearchNode == nil) )
{
WaitForLocalNode();
WaitForDHCPLDAPv3Init();
WaitForContactsSearchNode();
}
else if ( (inMatch == eDSNetworkSearchNodeName) && (fNetworkSearchNode == nil) )
{
WaitForLocalNode(); WaitForNetworkSearchNode();
}
else if ( (inMatch == eDSDefaultNetworkNodes) && (fNetworkSearchNode == nil) )
{
WaitForLocalNode(); }
else if ( (inMatch == eDSConfigNodeName) && (fConfigureNode == nil) )
{
WaitForConfigureNode();
}
fMutex.Wait();
try
{
if ( inMatch == eDSAuthenticationSearchNodeName )
{
if ( fAuthenticationSearchNode != nil )
{
if ( fAuthenticationSearchNode->fDataListPtr != nil )
{
siResult = AddNodePathToTDataBuff( fAuthenticationSearchNode->fDataListPtr, inBuff );
}
}
}
else if ( inMatch == eDSContactsSearchNodeName )
{
if ( fContactsSearchNode != nil )
{
if ( fContactsSearchNode->fDataListPtr != nil )
{
siResult = AddNodePathToTDataBuff( fContactsSearchNode->fDataListPtr, inBuff );
}
}
}
else if ( inMatch == eDSNetworkSearchNodeName )
{
if ( fNetworkSearchNode != nil )
{
if ( fNetworkSearchNode->fDataListPtr != nil )
{
siResult = AddNodePathToTDataBuff( fNetworkSearchNode->fDataListPtr, inBuff );
}
}
}
else if ( inMatch == eDSConfigNodeName )
{
if ( fConfigureNode != nil )
{
if ( fConfigureNode->fDataListPtr != nil )
{
siResult = AddNodePathToTDataBuff( fConfigureNode->fDataListPtr, inBuff );
}
}
}
else if ( inMatch == eDSLocalNodeNames )
{
if ( fLocalNode != nil )
{
if ( fLocalNode->fDataListPtr != nil )
{
siResult = AddNodePathToTDataBuff( fLocalNode->fDataListPtr, inBuff );
}
}
}
else if ( inMatch == eDSLocalHostedNodes )
{
siResult = this->DoGetNode( fLocalHostedNodes, inStr, inMatch, inBuff, &outNodePtr );
}
else if ( inMatch == eDSDefaultNetworkNodes )
{
siResult = this->DoGetNode( fDefaultNetworkNodes, inStr, inMatch, inBuff, &outNodePtr );
}
else
{
siResult = this->DoGetNode( fTreePtr, inStr, inMatch, inBuff, &outNodePtr );
}
}
catch( sInt32 err )
{
}
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList::DoGetNode ( sTreeNode *inLeaf,
char *inStr,
tDirPatternMatch inMatch,
tDataBuffer *inBuff,
sTreeNode **outNodePtr )
{
char *aString1 = nil;
char *aString2 = nil;
bool bAddToBuff = false;
sInt32 uiStrLen = 0;
sInt32 uiInStrLen = 0;
sInt32 siResult = eDSNoErr;
if ( inLeaf != nil )
{
siResult = DoGetNode( inLeaf->left, inStr, inMatch, inBuff, outNodePtr );
switch( inMatch )
{
case eDSLocalNodeNames:
if ( inLeaf->fType == kLocalNodeType )
{
bAddToBuff = true;
}
break;
case eDSAuthenticationSearchNodeName:
if ( inLeaf->fType == kSearchNodeType )
{
bAddToBuff = true;
}
break;
case eDSContactsSearchNodeName:
if ( inLeaf->fType == kContactsSearchNodeType )
{
bAddToBuff = true;
}
break;
case eDSNetworkSearchNodeName:
if ( inLeaf->fType == kNetworkSearchNodeType )
{
bAddToBuff = true;
}
break;
case eDSConfigNodeName:
if ( inLeaf->fType == kConfigNodeType )
{
bAddToBuff = true;
}
break;
case eDSLocalHostedNodes:
if ( inLeaf->fType == kLocalHostedType )
{
bAddToBuff = true;
}
break;
case eDSDefaultNetworkNodes:
if ( inLeaf->fType == kDefaultNetworkNodeType )
{
bAddToBuff = true;
}
break;
case eDSExact:
if ( ::strcmp( inLeaf->fNodeName, inStr ) == 0 )
{
bAddToBuff = true;
}
break;
case eDSStartsWith:
uiInStrLen = ::strlen( inStr );
if ( ::strncmp( inLeaf->fNodeName, inStr, uiInStrLen ) == 0 )
{
bAddToBuff = true;
}
break;
case eDSEndsWith:
uiInStrLen = ::strlen( inStr );
if (uiInStrLen > 1) {
uiStrLen = ::strlen( inLeaf->fNodeName );
if ( uiInStrLen <= uiStrLen )
{
aString1 = inLeaf->fNodeName + (uiStrLen - uiInStrLen + 1);
aString2 = inStr + 1;
if ( ::strcmp( aString1, aString2 ) == 0 )
{
bAddToBuff = true;
}
}
}
break;
case eDSContains:
uiInStrLen = ::strlen( inStr );
if (uiInStrLen > 1) {
aString2 = inStr + 1;
if ( ::strstr( inLeaf->fNodeName, aString2 ) != nil )
{
bAddToBuff = true;
}
}
break;
case eDSiExact:
uiInStrLen = ::strlen( inStr );
uiStrLen = ::strlen( inLeaf->fNodeName );
if ( uiInStrLen == uiStrLen )
{
aString1 = inStr;
aString2 = inLeaf->fNodeName;
bAddToBuff = true;
while ( *aString1 != '\0' )
{
if ( ::toupper( *aString2 ) != ::toupper( *aString1 ) )
{
bAddToBuff = false;
break;
}
aString2++;
aString1++;
}
}
break;
case eDSiStartsWith:
uiInStrLen = ::strlen( inStr );
uiStrLen = ::strlen( inLeaf->fNodeName );
if ( uiInStrLen <= uiStrLen )
{
aString1 = inStr;
aString2 = inLeaf->fNodeName;
bAddToBuff = true;
while ( *aString1 != '\0' )
{
if ( ::toupper( *aString2 ) != ::toupper( *aString1 ) )
{
bAddToBuff = false;
break;
}
aString2++;
aString1++;
}
}
break;
case eDSiEndsWith:
uiInStrLen = ::strlen( inStr );
if (uiInStrLen > 1) {
uiStrLen = ::strlen( inLeaf->fNodeName );
if ( uiInStrLen <= uiStrLen )
{
aString1 = inStr + 1;
aString2 = inLeaf->fNodeName + ( uiStrLen - uiInStrLen + 1 );
bAddToBuff = true;
while ( *aString1 != '\0' )
{
if ( ::toupper( *aString2 ) != ::toupper( *aString1 ) )
{
bAddToBuff = false;
break;
}
aString2++;
aString1++;
}
}
}
break;
case eDSiContains:
uiInStrLen = ::strlen( inStr );
if (uiInStrLen > 1) {
uiStrLen = ::strlen( inLeaf->fNodeName );
if ( uiInStrLen <= uiStrLen )
{
CString tmpStr1( 128 );
CString tmpStr2( 128 );
aString1 = inStr + 1;
aString2 = inLeaf->fNodeName;
bAddToBuff = false;
while ( *aString1 != '\0' )
{
tmpStr1.Append( ::toupper( *aString1 ) );
aString1++;
}
while ( *aString2 != '\0' )
{
tmpStr2.Append( ::toupper( *aString2 ) );
aString2++;
}
if ( ::strstr( tmpStr2.GetData(), tmpStr1.GetData() ) != nil )
{
bAddToBuff = true;
}
}
}
break;
default:
break;
}
if ( bAddToBuff == true )
{
siResult = AddNodePathToTDataBuff( inLeaf->fDataListPtr, inBuff );
*outNodePtr = inLeaf;
}
if ( siResult == eDSNoErr )
{
siResult = DoGetNode( inLeaf->right, inStr, inMatch, inBuff, outNodePtr );
}
}
return( siResult );
}
bool CNodeList::DeleteNode ( char *inStr )
{
bool found = false;
fMutex.Wait();
found = DeleteNodeFromTree( inStr, fLocalHostedNodes );
found = DeleteNodeFromTree( inStr, fDefaultNetworkNodes ) || found;
if (DeleteNodeFromTree( inStr, fTreePtr ))
{
found = true;
fCount--;
fNodeChangeToken++;
gSrvrCntl->NotifyDirNodeDeleted(inStr);
}
fMutex.Signal();
return( found );
}
bool CNodeList::DeleteNodeFromTree ( char *inStr, sTreeNode *inTree )
{
bool found = false;
sInt32 siResult = 0;
sTreeNode *aTree = inTree;
sTreeNode *aTreeParent = nil;
sTreeNode *remTree = nil;
sTreeNode *remTreeParent = nil;
sTreeNode *remTreeChild = nil;
eDirNodeType aDirNodeType = kUnknownNodeType;
fMutex.Wait();
if (aTree == fLocalHostedNodes)
{
aDirNodeType = kLocalHostedType;
}
else if (aTree == fDefaultNetworkNodes)
{
aDirNodeType = kDefaultNetworkNodeType;
}
else if (aTree == fTreePtr)
{
aDirNodeType = kDirNodeType;
}
else
{
aTree = nil;
}
while ( (!found) && (aTree != nil) )
{
siResult = CompareString( inStr, aTree->fNodeName );
if ( siResult == 0 )
{
found = true;
}
else
{
aTreeParent = aTree;
if ( siResult < 0 )
{
aTree = aTree->left;
}
else
{
aTree = aTree->right;
}
}
}
if ( found == true )
{
if ( aTree->left == nil )
{
remTree = aTree->right;
}
else
{
if ( aTree->right == nil )
{
remTree = aTree->left;
}
else
{
remTreeParent = aTree;
remTree = aTree->right;
remTreeChild = remTree->left;
while ( remTreeChild != nil )
{
remTreeParent = remTree;
remTree = remTreeChild;
remTreeChild = remTree->left;
}
if ( remTreeParent != aTree )
{
remTreeParent->left = remTree->right;
remTree->right = aTree->right;
}
remTree->left = aTree->left;
}
}
if ( aTreeParent == nil )
{
if (aDirNodeType == kLocalHostedType)
{
fLocalHostedNodes = remTree;
}
else if (aDirNodeType == kDefaultNetworkNodeType)
{
fDefaultNetworkNodes = remTree;
}
else if (aDirNodeType == kDirNodeType)
{
fTreePtr = remTree;
}
}
else
{
if ( aTree == aTreeParent->left )
{
aTreeParent->left = remTree;
}
else
{
aTreeParent->right = remTree;
}
}
if ( aTree->fNodeName != nil )
{
free( aTree->fNodeName );
aTree->fNodeName = nil;
}
if ( aTree->fDataListPtr != nil )
{
::dsDataListDeallocatePriv( aTree->fDataListPtr );
free ( aTree->fDataListPtr );
aTree->fDataListPtr = nil;
}
delete( aTree );
}
fMutex.Signal();
return( found );
}
bool CNodeList::IsPresent ( const char *inStr, eDirNodeType inType )
{
bool found = false;
sInt32 siResult = 0;
sTreeNode *current = nil;
fMutex.Wait();
if ( inType & ( kSearchNodeType | kContactsSearchNodeType | kNetworkSearchNodeType | kConfigNodeType | kLocalNodeType) )
{
fMutex.Signal();
return false;
}
else if (inType == kLocalHostedType)
{
current = fLocalHostedNodes;
}
else if (inType == kDefaultNetworkNodeType)
{
current = fDefaultNetworkNodes;
}
else {
current = fTreePtr;
}
while ( (!found) && (current != nil) )
{
siResult = CompareString( inStr, current->fNodeName );
if ( siResult == 0 )
{
found = true;
}
else
{
if ( siResult < 0 )
{
current = current->left;
}
else
{
current = current->right;
}
}
}
fMutex.Signal();
return( found );
}
bool CNodeList::GetPluginHandle ( const char *inStr, CServerPlugin **outPlugInPtr )
{
bool found = false;
sInt32 siResult = 0;
sTreeNode *current = nil;
fMutex.Wait();
if ( fLocalNode != nil)
{
if (fLocalNode->fNodeName != nil)
{
if (strcmp(inStr,fLocalNode->fNodeName) == 0)
{
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(fLocalNode);
}
fMutex.Signal();
return( true );
}
}
}
if (strlen(inStr) > 6 ) {
if ( strncmp(inStr+1,"Search",6) == 0 ) {
if ( fAuthenticationSearchNode != nil)
{
if (fAuthenticationSearchNode->fNodeName != nil)
{
if (strcmp(inStr,fAuthenticationSearchNode->fNodeName) == 0)
{
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(fAuthenticationSearchNode);
}
fMutex.Signal();
return( true );
}
}
}
if ( fNetworkSearchNode != nil)
{
if (fNetworkSearchNode->fNodeName != nil)
{
if (strcmp(inStr,fNetworkSearchNode->fNodeName) == 0)
{
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(fNetworkSearchNode);
}
fMutex.Signal();
return( true );
}
}
}
if ( fContactsSearchNode != nil)
{
if (fContactsSearchNode->fNodeName != nil)
{
if (strcmp(inStr,fContactsSearchNode->fNodeName) == 0)
{
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(fContactsSearchNode);
}
fMutex.Signal();
return( true );
}
}
}
}
}
current = fTreePtr;
while ( (!found) && (current != nil) )
{
siResult = CompareString( inStr, current->fNodeName );
if ( siResult == 0 )
{
found = true;
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(current);
}
}
else
{
if ( siResult < 0 )
{
current = current->left;
}
else
{
current = current->right;
}
}
}
if ( fConfigureNode != nil)
{
if (fConfigureNode->fNodeName != nil)
{
if (strcmp(inStr,fConfigureNode->fNodeName) == 0)
{
found = true;
if ( outPlugInPtr != nil )
{
*outPlugInPtr = GetPluginPtr(fConfigureNode);
}
}
}
}
fMutex.Signal();
return( found );
}
CServerPlugin* CNodeList::GetPluginPtr( sTreeNode* nodePtr )
{
if ( nodePtr->fPlugInPtr == nil )
{
nodePtr->fPlugInPtr = gPlugins->GetPlugInPtr( nodePtr->fPlugInToken, true );
}
return nodePtr->fPlugInPtr;
}
sInt32 CNodeList::CompareString ( const char *inStr_1, const char *inStr_2 )
{
volatile sInt32 siResult = -22;
if ( (inStr_1 != nil) && (inStr_2 != nil) )
{
siResult = ::strcmp( inStr_1, inStr_2 );
}
return( siResult );
}
sInt32 CNodeList::BuildNodeListBuff ( sGetDirNodeList *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 outCount = 0;
fMutex.Wait();
inData->fIOContinueData = nil;
siResult = this->DoBuildNodeListBuff( fTreePtr, inData->fOutDataBuff, &outCount );
inData->fOutNodeCount = outCount;
fMutex.Signal();
return( siResult );
}
sInt32 CNodeList::DoBuildNodeListBuff ( sTreeNode *inTree, tDataBuffer *inBuff, uInt32 *outCount )
{
sInt32 siResult = eDSNoErr;
tDataList *pNodeList = nil;
if ( inTree != nil )
{
siResult = DoBuildNodeListBuff( inTree->left, inBuff, outCount );
if ( siResult == eDSNoErr )
{
pNodeList = inTree->fDataListPtr;
if ( pNodeList != nil )
{
siResult = AddNodePathToTDataBuff( pNodeList, inBuff );
if ( siResult == eDSNoErr )
{
*outCount += 1;
siResult = DoBuildNodeListBuff( inTree->right, inBuff, outCount );
}
else
{
*outCount = 0;
}
}
}
}
return( siResult );
}
sInt32 CNodeList::AddNodePathToTDataBuff ( tDataList *inPtr, tDataBuffer *inBuff )
{
sInt32 siResult = eDSBufferTooSmall;
FourCharCode uiBuffType = 'npss'; uInt32 inBuffType = 'xxxx';
char *segmentStr = nil;
uInt16 uiStrLen = 0;
uInt32 uiItemCnt = 0;
uInt16 segmentCnt = 0;
uInt32 pathLength = 0;
uInt32 iSegment = 0;
uInt32 offset = 0;
if ( (inPtr != nil) && (inBuff != nil) )
{
if ( inBuff->fBufferSize > 7 )
{
::memcpy( &inBuffType, inBuff->fBufferData, 4 );
if (inBuffType != uiBuffType) {
::memcpy( inBuff->fBufferData, &uiBuffType, 4 );
inBuff->fBufferLength = 0;
}
else
{
::memcpy( &uiItemCnt, inBuff->fBufferData + 4, 4 );
}
segmentCnt = (uInt16) dsDataListGetNodeCountPriv( inPtr );
pathLength = dsGetDataLengthPriv ( inPtr );
pathLength += segmentCnt * 2 + 2;
if ( ( inBuff->fBufferLength + pathLength + 8) <= (inBuff->fBufferSize - ((uiItemCnt+1) * 4)) )
{
uiItemCnt++;
::memcpy( inBuff->fBufferData + 4, &uiItemCnt, 4 );
offset = inBuff->fBufferLength + 8; ::memcpy( inBuff->fBufferData + inBuff->fBufferSize - (uiItemCnt * 4) , &(offset), 4 );
::memcpy( inBuff->fBufferData + 8 + inBuff->fBufferLength, &segmentCnt, 2 );
inBuff->fBufferLength += 2;
for (iSegment = 1; iSegment <= segmentCnt; iSegment++ )
{
segmentStr = dsDataListGetNodeStringPriv( inPtr, iSegment );
if (segmentStr != nil);
{
uiStrLen = strlen(segmentStr);
::memcpy( inBuff->fBufferData + 8 + inBuff->fBufferLength, &uiStrLen, 2 );
::memcpy( inBuff->fBufferData + 8 + inBuff->fBufferLength + 2, segmentStr, uiStrLen );
free(segmentStr);
segmentStr = nil;
inBuff->fBufferLength += 2 + uiStrLen;
}
}
siResult = eDSNoErr;
}
else
{
siResult = eDSBufferTooSmall;
}
}
}
return( siResult );
}
void CNodeList::WaitForAuthenticationSearchNode( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForAuthenticationSN.Wait();
while ( fAuthenticationSearchNode == nil )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
waitTime = dsTimestamp() + USEC_PER_SEC*2;
bool bHitCondition = true;
while ( fAuthenticationSearchNode != nil )
{
if ( fAuthenticationSearchNode->fPlugInPtr != nil )
{
uInt32 uiState = 0;
sInt32 stateResult = gPlugins->GetState( fAuthenticationSearchNode->fPlugInPtr->GetPluginName(), &uiState );
if ( (stateResult == eDSNoErr) && ( uiState & kActive ) )
{
break;
}
if (bHitCondition)
{
DBGLOG( kLogApplication, "Hit the Search plugin race condition between init and active" );
bHitCondition = false;
}
}
timedWait.Wait( (uInt32)(.2 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForAuthenticationSN.Signal();
}
void CNodeList:: WaitForContactsSearchNode ( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForContactsSN.Wait();
while ( fContactsSearchNode == nil )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
waitTime = dsTimestamp() + USEC_PER_SEC*2;
bool bHitCondition = true;
while ( fContactsSearchNode != nil )
{
if ( fContactsSearchNode->fPlugInPtr != nil )
{
uInt32 uiState = 0;
sInt32 stateResult = gPlugins->GetState( fContactsSearchNode->fPlugInPtr->GetPluginName(), &uiState );
if ( (stateResult == eDSNoErr) && ( uiState & kActive ) )
{
break;
}
if (bHitCondition)
{
DBGLOG( kLogApplication, "Hit the Search plugin race condition between init and active" );
bHitCondition = false;
}
}
timedWait.Wait( (uInt32)(.2 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForContactsSN.Signal();
}
void CNodeList:: WaitForNetworkSearchNode ( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForNetworkSN.Wait();
while ( fNetworkSearchNode == nil )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
waitTime = dsTimestamp() + USEC_PER_SEC*2;
bool bHitCondition = true;
while ( fNetworkSearchNode != nil )
{
if ( fNetworkSearchNode->fPlugInPtr != nil )
{
uInt32 uiState = 0;
sInt32 stateResult = gPlugins->GetState( fNetworkSearchNode->fPlugInPtr->GetPluginName(), &uiState );
if ( (stateResult == eDSNoErr) && ( uiState & kActive ) )
{
break;
}
if (bHitCondition)
{
DBGLOG( kLogApplication, "Hit the Search plugin race condition between init and active" );
bHitCondition = false;
}
}
timedWait.Wait( (uInt32)(.2 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForNetworkSN.Signal();
}
void CNodeList::WaitForLocalNode( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForLN.Wait();
while ( fLocalNode == nil )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
waitTime = dsTimestamp() + USEC_PER_SEC*2;
bool bHitCondition = true;
while ( fLocalNode != nil )
{
if ( fLocalNode->fPlugInPtr != nil )
{
uInt32 uiState = 0;
sInt32 stateResult = gPlugins->GetState( fLocalNode->fPlugInPtr->GetPluginName(), &uiState );
if ( (stateResult == eDSNoErr) && ( uiState & kActive ) )
{
break;
}
if (bHitCondition)
{
DBGLOG( kLogApplication, "Hit the Local Netinfo plugin race condition between init and active" );
bHitCondition = false;
}
}
timedWait.Wait( (uInt32)(.2 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForLN.Signal();
}
void CNodeList::WaitForConfigureNode( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForConfigureN.Wait();
while ( fConfigureNode == nil )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
waitTime = dsTimestamp() + USEC_PER_SEC*2;
bool bHitCondition = true;
while ( fConfigureNode != nil )
{
if ( fConfigureNode->fPlugInPtr != nil )
{
uInt32 uiState = 0;
sInt32 stateResult = gPlugins->GetState( fConfigureNode->fPlugInPtr->GetPluginName(), &uiState );
if ( (stateResult == eDSNoErr) && ( uiState & kActive ) )
{
break;
}
if (bHitCondition)
{
DBGLOG( kLogApplication, "Hit the Configure plugin race condition between init and active" );
bHitCondition = false;
}
}
timedWait.Wait( (uInt32)(.2 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForConfigureN.Signal();
}
void CNodeList::WaitForDHCPLDAPv3Init( void )
{
DSSemaphore timedWait;
double waitTime = dsTimestamp() + USEC_PER_SEC*120;
fWaitForDHCPLDAPv3InitFlag.Wait();
while ( !bDHCPLDAPv3InitComplete )
{
timedWait.Wait( (uInt32)(.5 * kMilliSecsPerSec) );
if ( dsTimestamp() > waitTime )
{
break;
}
}
fWaitForDHCPLDAPv3InitFlag.Signal();
}