#include "BSDConfigureNode.h"
#include "NISNode.h"
#include "BSDPlugin.h"
#include "CSharedData.h"
DSEventSemaphore gKickBSDRequests;
BSDPlugin::BSDPlugin( FourCharCode inSig, const char *inName ) : BaseDirectoryPlugin( inSig, inName )
{
NISNode::InitializeGlobals();
fFlatFilesNode = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR("%@/%@"), fPluginPrefixCF, CFSTR("local") );
fNISDomainName = NISNode::CopyDomainName();
if ( DSIsStringEmpty(fNISDomainName) == false )
fNISDomainNode = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR("%@/%s"), fPluginPrefixCF, fNISDomainName );
else
fNISDomainNode = NULL;
fCustomCallReadConfig = 'read';
fCustomCallWriteConfig = 'writ';
}
BSDPlugin::~BSDPlugin( void )
{
UnregisterNode( fFlatFilesNode, kDirNodeType );
UnregisterNode( fFlatFilesNode, kLocalHostedType );
if (fNISDomainNode != NULL)
UnregisterNode( fNISDomainNode, kDirNodeType );
DSCFRelease( fNISDomainNode );
DSCFRelease( fFlatFilesNode );
DSFree( fNISDomainName );
}
SInt32 BSDPlugin::Initialize( void )
{
RegisterNode( fFlatFilesNode, kDirNodeType );
RegisterNode( fFlatFilesNode, kLocalHostedType );
RegisterNode( fFlatFilesNode, kBSDNodeType );
if ( fNISDomainNode != NULL )
RegisterNode( fNISDomainNode, kDirNodeType );
return BaseDirectoryPlugin::Initialize();
}
SInt32 BSDPlugin::SetPluginState( const UInt32 inState )
{
BaseDirectoryPlugin::SetPluginState( inState );
if (inState & kActive)
{
gKickBSDRequests.PostEvent();
}
return eDSNoErr;
}
SInt32 BSDPlugin::PeriodicTask( void )
{
static int checkTime = 0;
if ( (++checkTime) >= 10 )
{
if ( fNISDomainNode != NULL )
NISNode::IsNISAvailable();
checkTime = 0;
}
return eDSNoErr;
}
CFDataRef BSDPlugin::CopyConfiguration( void )
{
CFMutableDictionaryRef currentStateRef = CFDictionaryCreateMutable( NULL, 0, &kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks );
CFDataRef xmlData = NULL;
if ( currentStateRef == NULL )
return NULL;
if ( DSIsStringEmpty(fNISDomainName) == false )
{
CFStringRef cfNISDomainName = CFStringCreateWithCString( kCFAllocatorDefault, fNISDomainName, kCFStringEncodingUTF8 );
if ( cfNISDomainName != NULL )
CFDictionarySetValue( currentStateRef, CFSTR(kDS1AttrLocation), cfNISDomainName );
char *nisServers = NISNode::CopyNISServers( fNISDomainName );
if ( nisServers != NULL )
{
CFStringRef cfNISServers = CFStringCreateWithCString( kCFAllocatorDefault, nisServers, kCFStringEncodingUTF8 );
if ( cfNISServers != NULL )
{
CFDictionarySetValue( currentStateRef, CFSTR(kDSStdRecordTypeServer), cfNISServers );
DSCFRelease( cfNISServers );
}
DSFree( nisServers );
}
DSCFRelease( cfNISDomainName );
}
xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, currentStateRef );
DSCFRelease( currentStateRef );
return xmlData;
}
bool BSDPlugin::NewConfiguration( const char *inData, UInt32 inLength )
{
if ( CheckConfiguration(inData, inLength) == false )
return false;
CFDataRef xmlData = CFDataCreate( kCFAllocatorDefault, (UInt8 *)inData, inLength );
CFDictionaryRef newStateRef = (CFDictionaryRef) CFPropertyListCreateFromXMLData( kCFAllocatorDefault, xmlData,
kCFPropertyListImmutable, NULL );
char *pTemp = NULL;
char *pTemp2 = NULL;
const char *pNewDomainName = NULL;
const char *pServers = NULL;
fBasePluginMutex.WaitLock();
UnregisterNode( fNISDomainNode, kDirNodeType );
DSFree( fNISDomainName );
DSCFRelease( fNISDomainNode );
CFStringRef newDomainName = (CFStringRef) CFDictionaryGetValue( newStateRef, CFSTR(kDS1AttrLocation) );
if ( newDomainName != NULL && CFStringGetLength(newDomainName) )
pNewDomainName = BaseDirectoryPlugin::GetCStringFromCFString( newDomainName, &pTemp );
CFStringRef nisServersRef = (CFStringRef) CFDictionaryGetValue( newStateRef, CFSTR(kDSStdRecordTypeServer) );
if ( nisServersRef != NULL )
pServers = BaseDirectoryPlugin::GetCStringFromCFString( nisServersRef, &pTemp2 );
if ( pNewDomainName != NULL )
{
fNISDomainName = strdup( pNewDomainName );
fNISDomainNode = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR("%@/%s"), fPluginPrefixCF, fNISDomainName );
NISNode::SetDomainAndServers( pNewDomainName, pServers );
RegisterNode( fNISDomainNode, kDirNodeType );
}
else
{
NISNode::SetDomainAndServers( NULL, NULL );
}
fBasePluginMutex.SignalLock();
DSFree( pTemp );
DSFree( pTemp2 );
DSCFRelease( newStateRef );
DSCFRelease( xmlData );
return true;
}
bool BSDPlugin::CheckConfiguration( const char *inData, UInt32 inLength )
{
CFDataRef xmlData = CFDataCreate( kCFAllocatorDefault, (UInt8 *)inData, inLength );
CFDictionaryRef newStateRef = NULL;
bool bReturn = false;
if ( xmlData != NULL )
{
newStateRef = (CFDictionaryRef) CFPropertyListCreateFromXMLData( kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL );
if ( newStateRef != NULL && CFGetTypeID(newStateRef) == CFDictionaryGetTypeID() )
{
CFStringRef newDomainName = (CFStringRef) CFDictionaryGetValue( newStateRef, CFSTR(kDS1AttrLocation) );
if ( newDomainName != NULL && CFGetTypeID(newDomainName) != CFStringGetTypeID() )
goto failure;
CFStringRef nisServersRef = (CFStringRef) CFDictionaryGetValue( newStateRef, CFSTR(kDSStdRecordTypeServer) );
if ( nisServersRef != NULL && CFGetTypeID(nisServersRef) != CFStringGetTypeID() )
goto failure;
bReturn = true;
}
}
failure:
DSCFRelease( xmlData );
DSCFRelease( newStateRef );
return bReturn;
}
tDirStatus BSDPlugin::HandleCustomCall( sBDPINodeContext *pContext, sDoPlugInCustomCall *inData )
{
tDirStatus siResult = eNotHandledByThisNode;
return siResult;
}
bool BSDPlugin::IsConfigureNodeName( CFStringRef inNodeName )
{
if ( CFStringCompare(fPluginPrefixCF, inNodeName, 0) == kCFCompareEqualTo )
return true;
return false;
}
BDPIVirtualNode *BSDPlugin::CreateNodeForPath( CFStringRef inPath, uid_t inUID, uid_t inEffectiveUID )
{
BDPIVirtualNode *pNewNode = NULL;
if ( CFStringCompare(fPluginPrefixCF, inPath, 0) == kCFCompareEqualTo )
{
pNewNode = new BSDConfigureNode( inPath, inUID, inEffectiveUID );
}
else if ( CFStringCompare(fFlatFilesNode, inPath, 0) == kCFCompareEqualTo )
{
pNewNode = new FlatFileNode( inPath, inUID, inEffectiveUID );
}
else if ( fNISDomainNode != NULL && CFStringCompare(fNISDomainNode, inPath, 0) == kCFCompareEqualTo && NISNode::IsNISAvailable() )
{
pNewNode = new NISNode( inPath, fNISDomainName, inUID, inEffectiveUID );
}
return pNewNode;
}