#include "CNiNodeList.h"
#include "CNetInfoPlugin.h"
#include "DSUtils.h"
#include "ServerModuleLib.h"
#include "CSharedData.h"
#include "CLog.h"
#include "CNiUtilities.h"
#include "netinfo_open.h"
CNiNodeList::CNiNodeList ( void )
{
}
CNiNodeList::~CNiNodeList ( void )
{
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
for (aNiNodeMapI = fNiNodeMap.begin(); aNiNodeMapI != fNiNodeMap.end(); ++aNiNodeMapI)
{
aNode = aNiNodeMapI->second;
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
free(aNode);
}
fNiNodeMap.clear();
}
void CNiNodeList::Lock ( void )
{
fMutex.Wait();
}
void CNiNodeList::UnLock ( void )
{
fMutex.Signal();
}
sInt32 CNiNodeList::AddNode ( const char *inStr, tDataList *inListPtr, bool inRegistered, uInt32 inLocalOrParent )
{
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI == fNiNodeMap.end()) {
aNode = (sNode *)::calloc( sizeof( sNode ), sizeof( char ) );
aNode->listPtr = inListPtr;
aNode->refCount = 1;
aNode->bisDirty = false;
aNode->fDomain = nil;
aNode->fDomainName = nil;
aNode->bRegistered = inRegistered;
aNode->localOrParent= inLocalOrParent;
fNiNodeMap[aNodeName] = aNode;
DBGLOG1( kLogPlugin, "CNiNodeList::AddNode - added the nodename %s", inStr);
}
else {
DBGLOG1( kLogPlugin, "CNiNodeList::AddNode - duplicate nodename %s", inStr);
aNode = aNiNodeMapI->second;
if (inRegistered)
{
if (aNode->localOrParent != inLocalOrParent)
{
DBGLOG1( kLogPlugin, "CNiNodeList::AddNode - hierarchy changed for nodename %s", inStr);
aNode->bRegistered = true;
aNode->localOrParent= inLocalOrParent;
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
if (aNode->fDomain != nil)
{
gNetInfoMutex->Wait();
DBGLOG( kLogPlugin, "CNiNodeList::AddNode - free the NI domain since it is being replaced");
gNetInfoMutex->Signal();
aNode->fDomain = nil;
}
}
if (aNode->bisDirty)
{
aNode->bisDirty = false;
}
}
else if ( !(aNode->bisDirty) ) {
if (inRegistered)
{
if (!(aNode->bRegistered))
{
aNode->bRegistered = true; aNode->refCount++; }
}
else {
aNode->refCount++;
}
}
if (aNode->listPtr == nil)
{
aNode->listPtr = inListPtr;
}
else
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
}
fMutex.Signal();
return( eDSNoErr );
}
void* CNiNodeList::DeleteNode ( const char *inStr )
{
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
void *domain = nil;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
aNode->refCount--;
if ( aNode->refCount < 1 )
{
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if ( (aNode->fDomain != nil) && !(aNode->bisDirty) )
{
domain = aNode->fDomain;
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
DBGLOG1( kLogPlugin, "CNiNodeList::DeleteNode - deleting the nodename %s", aNode->fDomainName);
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
fNiNodeMap.erase(aNodeName);
free(aNode);
}
}
fMutex.Signal();
return( domain );
}
bool CNiNodeList::IsPresent ( const char *inStr )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
{
found = true;
}
}
fMutex.Signal();
return( found );
}
bool CNiNodeList::IsPresent ( const char *inStr, tDataList **inListPtr )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
{
found = true;
if ( inListPtr != nil )
{
*inListPtr = aNode->listPtr;
}
}
}
fMutex.Signal();
return( found );
}
bool CNiNodeList::IsOpen ( const char *inStr,
char **outDomName )
{
bool isOpen = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if ( !(aNode->bisDirty) && (aNode->fDomain != nil) && (aNode->fDomainName != nil) )
{
*outDomName = strdup(aNode->fDomainName);
isOpen = true;
aNode->refCount++;
}
}
fMutex.Signal();
return( isOpen );
}
bool CNiNodeList::SetDomainInfo ( const char *inStr,
void *inDomain,
char *inDomainName )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI == fNiNodeMap.end()) {
tDataListPtr pDataList = ::dsBuildFromPathPriv( inDomainName, "/" );
this->AddNode(inStr, pDataList, true); aNiNodeMapI = fNiNodeMap.find(aNodeName);
}
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if ( ( inDomain != nil ) && ( inDomainName != nil ) )
{
aNode->fDomain = inDomain;
if ( aNode->fDomainName )
free(aNode->fDomainName);
aNode->fDomainName = strdup(inDomainName);
aNode->bisDirty = false;
aNode->refCount++;
found = true;
}
}
fMutex.Signal();
return( found );
}
void CNiNodeList::CleanUpUnknownConnections ( const uInt32 inSignature )
{
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
for (aNiNodeMapI = fNiNodeMap.begin(); aNiNodeMapI != fNiNodeMap.end(); ++aNiNodeMapI)
{
aNode = aNiNodeMapI->second;
if (( aNode->bRegistered ) && (aNode->localOrParent != 1)) {
if (aNode->fDomainName != NULL)
{
char *aNodeName = BuildDomainPathFromName(aNode->fDomainName);
if (aNodeName != NULL)
{
DBGLOG1( kLogPlugin, "CNiNodeList::CleanUpUnknownConnections - about to clean the nodename %s", aNodeName);
free(aNodeName);
aNodeName = NULL;
}
CNetInfoPlugin::UnregisterNode( inSignature, aNode->listPtr ); if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
DBGLOG1( kLogPlugin, "CNiNodeList::CleanUpUnknownConnections - cleaning the nodename %s", aNode->fDomainName);
aNode->fDomainName = nil;
}
fNiNodeMap.erase(aNiNodeMapI);
free(aNode);
aNiNodeMapI = fNiNodeMap.begin();
}
}
}
gNetInfoMutex->Wait();
netinfo_clear(NETINFO_CLEAR_PRESERVE_LOCAL);
gNetInfoMutex->Signal();
fMutex.Signal();
}
uInt32 CNiNodeList::CheckForLocalOrParent ( const char *inName )
{
string aNodeName(inName);
uInt32 localOrParent = 0;
NiNodeMapI aNiNodeMapI;
sNode *aNode = nil;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
localOrParent = aNode->localOrParent;
}
fMutex.Signal();
return (localOrParent);
}
void* CNiNodeList::RetrieveNode ( const char *inName )
{
string aNodeName(inName);
void *aDomain = NULL;
NiNodeMapI aNiNodeMapI;
sNode *aNode = nil;
fMutex.Wait();
if (strcmp(inName, kstrDefaultLocalNodeName) == 0 )
{
aNiNodeMapI = fNiNodeMap.find(kstrLocalDot);
}
else
{
aNiNodeMapI = fNiNodeMap.find(aNodeName);
}
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
aDomain = aNode->fDomain;
}
else
{
DBGLOG1( kLogPlugin, "CNiNodeList::RetrieveNode - did not find the nodename %s", inName);
}
fMutex.Signal();
return (aDomain);
}
void CNiNodeList::AdjustForParent ( void )
{
string aNodeName("/");
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if (aNode != nil)
{
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
aNode->bisDirty = true;
aNode->localOrParent = 0;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
}
}
fMutex.Signal();
return;
}
void* CNiNodeList::RetrieveLocalDomain ( const char *inStr )
{
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
void *domain = nil;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if (aNode->fDomain != nil)
{
domain = aNode->fDomain;
}
}
fMutex.Signal();
return( domain );
}