#if DEBUG_SRVR
# include <stdio.h> // for stderr, fprintf(), et al
#endif
#include "ServerControl.h"
#include "CHandlers.h"
#include "CListener.h"
#include "DSTCPListener.h"
#include "CMsgQueue.h"
#include "CRefTable.h"
#include "DSMutexSemaphore.h"
#include "DSCThread.h"
#include "CServerPlugin.h"
#include "CPluginHandler.h"
#include "CNodeList.h"
#include "CLog.h"
#include <LDAP/ldap.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <sys/stat.h> //used for mkdir and stat
#include <servers/bootstrap.h>
#include <IOKit/pwr_mgt/IOPMLib.h> //required for power management handling
#include <syslog.h> // for syslog()
#include <time.h> // for time
extern void dsPMNotificationHandler ( void *refContext, io_service_t service, natural_t messageType, void *notificationID );
extern io_object_t gPMDeregisterNotifier;
extern io_connect_t gPMKernelPort;
extern boolean_t NetworkChangeCallBack(SCDynamicStoreRef aSCDStore, void *callback_argument);
extern CFRunLoopRef gServerRunLoop;
extern time_t gSunsetTime;
extern dsBool gLogAPICalls;
ServerControl *gSrvrCntl = nil;
CRefTable *gRefTable = nil;
CPlugInList *gPlugins = nil;
CMsgQueue *gTCPMsgQueue = nil;
CMsgQueue *gMsgQueue = nil;
CMsgQueue *gInternalMsgQueue = nil;
CMsgQueue *gCheckpwMsgQueue = nil;
CNodeList *gNodeList = nil;
name_t gServerName = "DirectoryService"; DSMutexSemaphore *gTCPHandlerLock = new DSMutexSemaphore(); DSMutexSemaphore *gHandlerLock = new DSMutexSemaphore(); DSMutexSemaphore *gInternalHandlerLock = new DSMutexSemaphore(); DSMutexSemaphore *gCheckpwHandlerLock = new DSMutexSemaphore();
uInt32 gDaemonPID;
uInt32 gDaemonIPAddress;
static mach_port_t gClient_Death_Notify_Port = NULL;
void ClientDeathCallback(CFMachPortRef port, void *voidmsg, CFIndex size, void *info);
void ClientDeathCallback(CFMachPortRef port, void *voidmsg, CFIndex size, void *info)
{
mach_msg_header_t *msg = (mach_msg_header_t *)voidmsg;
if (msg->msgh_id == MACH_NOTIFY_DEAD_NAME)
{
const mach_dead_name_notification_t *const deathMessage = (mach_dead_name_notification_t *)msg;
DBGLOG1( kLogApplication, "Client that used port %d has died or port has been deallocated.", deathMessage->not_port );
mach_port_destroy( mach_task_self(), deathMessage->not_port );
}
}
void EnableDeathNotificationForClient(mach_port_t port);
void EnableDeathNotificationForClient(mach_port_t port)
{
mach_port_t prev;
if (gClient_Death_Notify_Port != NULL)
{
kern_return_t r = mach_port_request_notification( mach_task_self(),
port,
MACH_NOTIFY_DEAD_NAME,
0,
gClient_Death_Notify_Port,
MACH_MSG_TYPE_MAKE_SEND_ONCE,
&prev);
if (r != KERN_SUCCESS)
{
DBGLOG1( kLogApplication, "Can't register for dead port notification since port %d already gone.", port );
}
}
}
void DoPeriodicTask(CFRunLoopTimerRef timer, void *info);
CFStringRef PeriodicTaskCopyStringCallback( const void *item );
CFStringRef PeriodicTaskCopyStringCallback( const void *item )
{
return CFSTR("PeriodicTask");
}
ServerControl::ServerControl ( void )
{
uInt32 i = 0;
gDaemonPID = getpid();
gDaemonIPAddress = 0;
fListener = nil;
fTCPListener = nil;
fTCPHandlerThreadsCnt = 0;
fHandlerThreadsCnt = 0;
fInternalHandlerThreadsCnt = 0;
fCheckpwHandlerThreadsCnt = 0;
fSCDStore = 0;
for ( i = 0; i < kMaxHandlerThreads; i++)
{
fTCPHandlers[ i ] = nil;
}
for ( i = 0; i < kMaxHandlerThreads; i++)
{
fHandlers[ i ] = nil;
}
for ( i = 0; i < kMaxInternalHandlerThreads; i++)
{
fInternalHandlers[ i ] = nil;
}
for ( i = 0; i < kMaxCheckpwHandlerThreads; i++)
{
fCheckpwHandlers[ i ] = nil;
}
fTCPHandlerSemaphore = new DSSemaphore( fTCPHandlerThreadsCnt );
fHandlerSemaphore = new DSSemaphore( fHandlerThreadsCnt );
fInternalHandlerSemaphore = new DSSemaphore( fInternalHandlerThreadsCnt );
fCheckpwHandlerSemaphore = new DSSemaphore( fCheckpwHandlerThreadsCnt );
}
ServerControl::~ServerControl ( void )
{
if ( fTCPHandlerSemaphore != nil )
{
delete( fTCPHandlerSemaphore );
fTCPHandlerSemaphore = nil;
}
if ( fHandlerSemaphore != nil )
{
delete( fHandlerSemaphore );
fHandlerSemaphore = nil;
}
if ( fInternalHandlerSemaphore != nil )
{
delete( fInternalHandlerSemaphore );
fInternalHandlerSemaphore = nil;
}
if ( fCheckpwHandlerSemaphore != nil )
{
delete( fCheckpwHandlerSemaphore );
fCheckpwHandlerSemaphore = nil;
}
}
sInt32 ServerControl::StartUpServer ( void )
{
sInt32 result = eDSNoErr;
struct stat statResult;
LDAP* aHost = nil;
int rc = LDAP_SUCCESS;
try
{
if ( gNodeList == nil )
{
gNodeList = new CNodeList;
if ( gNodeList == nil ) throw((sInt32)eMemoryAllocError);
}
if ( gRefTable == nil )
{
gRefTable = new CRefTable( CHandlerThread::RefDeallocProc );
if ( gRefTable == nil ) throw( (sInt32)eMemoryAllocError );
}
if ( gPlugins == nil )
{
gPlugins = new CPlugInList();
if ( gPlugins == nil ) throw( (sInt32)eMemoryAllocError );
}
if ( gTCPMsgQueue == nil )
{
gTCPMsgQueue = new CMsgQueue;
if ( gTCPMsgQueue == nil ) throw((sInt32)eMemoryAllocError);
}
if ( gMsgQueue == nil )
{
gMsgQueue = new CMsgQueue;
if ( gMsgQueue == nil ) throw((sInt32)eMemoryAllocError);
}
if ( gInternalMsgQueue == nil )
{
gInternalMsgQueue = new CMsgQueue;
if ( gInternalMsgQueue == nil ) throw((sInt32)eMemoryAllocError);
}
if ( gCheckpwMsgQueue == nil )
{
gCheckpwMsgQueue = new CMsgQueue;
if ( gCheckpwMsgQueue == nil ) throw((sInt32)eMemoryAllocError);
}
if (::stat( "/Library/Preferences/DirectoryService/.DSLogAPIAtStart", &statResult ) == eDSNoErr)
{
gLogAPICalls = true;
gSunsetTime = time(nil) + 300;
syslog(LOG_INFO,"Logging of API Calls turned ON at Startup of DS Daemon.");
}
rc = ldap_initialize(&aHost, NULL);
if (rc == LDAP_SUCCESS) {
ldap_unbind(aHost);
aHost = NULL;
}
result = StartListener();
if ( result != eDSNoErr ) throw( result );
if (::stat( "/Library/Preferences/DirectoryService/.DSTCPListening", &statResult ) == eDSNoErr)
{
result = StartTCPListener(kDSDefaultListenPort);
if ( result != eDSNoErr ) throw( result );
}
if ( gPluginHandler == nil )
{
gPluginHandler = new CPluginHandler;
if ( gPluginHandler == nil ) throw((sInt32)eMemoryAllocError);
gPluginHandler->StartThread();
}
result = (sInt32)RegisterForNetworkChange();
if ( result != eDSNoErr ) throw( result );
result = SetUpPeriodicTask();
if ( result != eDSNoErr ) throw( result );
}
catch( sInt32 err )
{
result = err;
}
return( result );
}
sInt32 ServerControl::ShutDownServer ( void )
{
sInt32 result = eDSNoErr;
uInt32 i = 0;
uInt32 uiStopCnt = 0;
struct stat statResult;
try
{
result = (sInt32)UnRegisterForNetworkChange();
if ( result != eDSNoErr ) throw( result );
fListener->StopThread();
if (::stat( "/Library/Preferences/DirectoryService/.DSTCPListening", &statResult ) == eDSNoErr)
{
if (fTCPListener != nil)
{
fTCPListener->StopThread();
gTCPHandlerLock->Wait();
for ( i = 0; i < kMaxHandlerThreads; i++ )
{
if ( fTCPHandlers[ i ] != nil )
{
uiStopCnt += 1;
fTCPHandlers[ i ]->StopThread();
fTCPHandlers[ i ] = nil;
}
}
gTCPHandlerLock->Signal();
while (uiStopCnt > 0)
{
WakeAHandler(DSCThread::kTSTCPHandlerThread);
uiStopCnt--;
}
uiStopCnt = 0;
}
}
gHandlerLock->Wait();
for ( i = 0; i < kMaxHandlerThreads; i++ )
{
if ( fHandlers[ i ] != nil )
{
uiStopCnt += 1;
fHandlers[ i ]->StopThread();
fHandlers[ i ] = nil;
}
}
gHandlerLock->Signal();
while (uiStopCnt > 0)
{
WakeAHandler(DSCThread::kTSHandlerThread);
uiStopCnt--;
}
uiStopCnt = 0;
gInternalHandlerLock->Wait();
for ( i = 0; i < kMaxInternalHandlerThreads; i++ )
{
if ( fInternalHandlers[ i ] != nil )
{
uiStopCnt += 1;
fInternalHandlers[ i ]->StopThread();
fInternalHandlers[ i ] = nil;
}
}
gInternalHandlerLock->Signal();
while (uiStopCnt > 0)
{
WakeAHandler(DSCThread::kTSInternalHandlerThread);
uiStopCnt--;
}
uiStopCnt = 0;
gCheckpwHandlerLock->Wait();
for ( i = 0; i < kMaxCheckpwHandlerThreads; i++ )
{
if ( fCheckpwHandlers[ i ] != nil )
{
uiStopCnt += 1;
fCheckpwHandlers[ i ]->StopThread();
fCheckpwHandlers[ i ] = nil;
}
}
gCheckpwHandlerLock->Signal();
while (uiStopCnt > 0)
{
WakeAHandler(DSCThread::kTSCheckpwHandlerThread);
uiStopCnt--;
}
if ( gNodeList != nil )
{
delete( gNodeList );
gNodeList = nil;
}
if ( gRefTable != nil )
{
delete( gRefTable );
gRefTable = nil;
}
if ( gPlugins != nil )
{
delete( gPlugins );
gPlugins = nil;
}
if ( gTCPMsgQueue != nil )
{
delete( gTCPMsgQueue );
gTCPMsgQueue = nil;
}
if ( gMsgQueue != nil )
{
delete( gMsgQueue );
gMsgQueue = nil;
}
if ( gInternalMsgQueue != nil )
{
delete( gInternalMsgQueue );
gInternalMsgQueue = nil;
}
if ( gCheckpwMsgQueue != nil )
{
delete( gCheckpwMsgQueue );
gCheckpwMsgQueue = nil;
}
delete(gTCPHandlerLock);
delete(gHandlerLock);
delete(gInternalHandlerLock);
delete(gCheckpwHandlerLock);
CLog::Deinitialize();
}
catch( sInt32 err )
{
result = err;
}
return( result );
}
sInt32 ServerControl::StartListener ( void )
{
sInt32 result = eDSNoErr;
try
{
fListener = new CListener();
if ( fListener == nil ) throw((sInt32)eMemoryAllocError);
fListener->StartThread();
}
catch( sInt32 err )
{
result = err;
DBGLOG2( kLogApplication, "File: %s. Line: %d", __FILE__, __LINE__ );
DBGLOG1( kLogApplication, " Caught exception = %d.", err );
}
if ( (result == eDSNoErr) && (gServerRunLoop != NULL) )
{
CFMachPortRef d_port = CFMachPortCreate(NULL, ClientDeathCallback, NULL, NULL);
CFRunLoopSourceRef d_rls = CFMachPortCreateRunLoopSource(NULL, d_port, 0);
gClient_Death_Notify_Port = CFMachPortGetPort(d_port);
CFRunLoopAddSource(gServerRunLoop, d_rls, kCFRunLoopDefaultMode);
CFRelease(d_rls);
}
return( result );
}
sInt32 ServerControl::StartTCPListener ( uInt32 inPort )
{
sInt32 result = eDSNoErr;
try
{
fTCPListener = new DSTCPListener(inPort);
if ( fTCPListener == nil ) throw((sInt32)eMemoryAllocError);
fTCPListener->StartThread();
}
catch( sInt32 err )
{
result = err;
DBGLOG2( kLogApplication, "File: %s. Line: %d", __FILE__, __LINE__ );
DBGLOG1( kLogApplication, " Caught exception = %d.", err );
}
return( result );
}
sInt32 ServerControl::StopTCPListener ( void )
{
sInt32 result = eDSNoErr;
try
{
if ( fTCPListener == nil ) throw((sInt32)eMemoryAllocError);
fTCPListener->StopThread();
}
catch( sInt32 err )
{
result = err;
DBGLOG2( kLogApplication, "File: %s. Line: %d", __FILE__, __LINE__ );
DBGLOG1( kLogApplication, " Caught exception = %d.", err );
}
return( result );
}
sInt32 ServerControl:: StartAHandler ( const FourCharCode inThreadSignature )
{
volatile uInt32 iThread;
sInt32 result = eDSNoErr;
try
{
if (inThreadSignature == DSCThread::kTSTCPHandlerThread)
{
if ( (fTCPHandlerThreadsCnt >= 0) && (fTCPHandlerThreadsCnt < kMaxHandlerThreads) )
{
for (iThread =0; iThread < kMaxHandlerThreads; iThread++)
{
if (fTCPHandlers[ iThread ] == nil)
{
fTCPHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSTCPHandlerThread, iThread);
if ( fTCPHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fTCPHandlerThreadsCnt++;
fTCPHandlers[ iThread ]->StartThread();
break;
}
else if ( fTCPHandlers[iThread]->GetOurThreadRunState() == DSCThread::kThreadStop)
{
fTCPHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSTCPHandlerThread, iThread);
if ( fTCPHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fTCPHandlers[ iThread ]->StartThread();
break;
}
}
}
}
if (inThreadSignature == DSCThread::kTSHandlerThread)
{
if ( (fHandlerThreadsCnt >= 0) && (fHandlerThreadsCnt < kMaxHandlerThreads) )
{
for (iThread =0; iThread < kMaxHandlerThreads; iThread++)
{
if (fHandlers[ iThread ] == nil)
{
fHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSHandlerThread, iThread);
if ( fHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fHandlerThreadsCnt++;
fHandlers[ iThread ]->StartThread();
break;
}
else if ( fHandlers[iThread]->GetOurThreadRunState() == DSCThread::kThreadStop)
{
fHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSHandlerThread, iThread);
if ( fHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fHandlers[ iThread ]->StartThread();
break;
}
}
}
}
if (inThreadSignature == DSCThread::kTSInternalHandlerThread)
{
if ( (fInternalHandlerThreadsCnt >= 0) && (fInternalHandlerThreadsCnt < kMaxInternalHandlerThreads) )
{
for (iThread =0; iThread < kMaxInternalHandlerThreads; iThread++)
{
if (fInternalHandlers[ iThread ] == nil)
{
fInternalHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSInternalHandlerThread, iThread);
if ( fInternalHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fInternalHandlerThreadsCnt++;
fInternalHandlers[ iThread ]->StartThread();
break;
}
else if ( fInternalHandlers[iThread]->GetOurThreadRunState() == DSCThread::kThreadStop)
{
fInternalHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSInternalHandlerThread, iThread);
if ( fInternalHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fInternalHandlers[ iThread ]->StartThread();
break;
}
}
}
}
if (inThreadSignature == DSCThread::kTSCheckpwHandlerThread)
{
if ( (fCheckpwHandlerThreadsCnt >= 0) && (fCheckpwHandlerThreadsCnt < kMaxCheckpwHandlerThreads) )
{
for (iThread =0; iThread < kMaxCheckpwHandlerThreads; iThread++)
{
if (fCheckpwHandlers[ iThread ] == nil)
{
fCheckpwHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSCheckpwHandlerThread, iThread);
if ( fCheckpwHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fCheckpwHandlerThreadsCnt++;
fCheckpwHandlers[ iThread ]->StartThread();
break;
}
else if ( fCheckpwHandlers[iThread]->GetOurThreadRunState() == DSCThread::kThreadStop)
{
fCheckpwHandlers[ iThread ] = new CHandlerThread(DSCThread::kTSCheckpwHandlerThread, iThread);
if ( fCheckpwHandlers[ iThread ] == nil ) throw((sInt32)eMemoryAllocError);
fCheckpwHandlers[ iThread ]->StartThread();
break;
}
}
}
}
}
catch( sInt32 err )
{
result = err;
}
return( result );
}
void ServerControl:: WakeAHandler ( const FourCharCode inThreadSignature )
{
if (inThreadSignature == DSCThread::kTSTCPHandlerThread)
{
fTCPHandlerSemaphore->Signal();
}
if (inThreadSignature == DSCThread::kTSHandlerThread)
{
fHandlerSemaphore->Signal();
}
if (inThreadSignature == DSCThread::kTSInternalHandlerThread)
{
fInternalHandlerSemaphore->Signal();
}
if (inThreadSignature == DSCThread::kTSCheckpwHandlerThread)
{
fCheckpwHandlerSemaphore->Signal();
}
}
sInt32 ServerControl:: StopAHandler ( const FourCharCode inThreadSignature, uInt32 iThread, CHandlerThread *inThread )
{
sInt32 result = eDSNoErr;
try
{
if (inThreadSignature == DSCThread::kTSTCPHandlerThread)
{
if ( (iThread >= 0) && (iThread < kMaxHandlerThreads) )
{
if (fTCPHandlers[ iThread ] == inThread)
{
fTCPHandlers[ iThread ] = nil;
fTCPHandlerThreadsCnt--;
}
}
}
if (inThreadSignature == DSCThread::kTSHandlerThread)
{
if ( (iThread >= 0) && (iThread < kMaxHandlerThreads) )
{
if (fHandlers[ iThread ] == inThread)
{
fHandlers[ iThread ] = nil;
fHandlerThreadsCnt--;
}
}
}
if (inThreadSignature == DSCThread::kTSInternalHandlerThread)
{
if ( (iThread >= 0) && (iThread < kMaxInternalHandlerThreads) )
{
if (fInternalHandlers[ iThread ] == inThread)
{
fInternalHandlers[ iThread ] = nil;
fInternalHandlerThreadsCnt--;
}
}
}
if (inThreadSignature == DSCThread::kTSCheckpwHandlerThread)
{
if ( (iThread >= 0) && (iThread < kMaxCheckpwHandlerThreads) )
{
if (fCheckpwHandlers[ iThread ] == inThread)
{
fCheckpwHandlers[ iThread ] = nil;
fCheckpwHandlerThreadsCnt--;
}
}
}
}
catch( sInt32 err )
{
result = err;
}
return( result );
}
void ServerControl:: SleepAHandler ( const FourCharCode inThreadSignature, uInt32 waitTime )
{
if (inThreadSignature == DSCThread::kTSTCPHandlerThread)
{
fTCPHandlerSemaphore->Wait( waitTime );
}
if (inThreadSignature == DSCThread::kTSHandlerThread)
{
fHandlerSemaphore->Wait( waitTime );
}
if (inThreadSignature == DSCThread::kTSInternalHandlerThread)
{
fInternalHandlerSemaphore->Wait( waitTime );
}
if (inThreadSignature == DSCThread::kTSCheckpwHandlerThread)
{
fCheckpwHandlerSemaphore->Wait( waitTime );
}
}
uInt32 ServerControl::GetHandlerCount ( const FourCharCode inThreadSignature )
{
if (inThreadSignature == DSCThread::kTSTCPHandlerThread)
{
return fTCPHandlerThreadsCnt;
}
if (inThreadSignature == DSCThread::kTSHandlerThread)
{
return fHandlerThreadsCnt;
}
if (inThreadSignature == DSCThread::kTSInternalHandlerThread)
{
return fInternalHandlerThreadsCnt;
}
if (inThreadSignature == DSCThread::kTSCheckpwHandlerThread)
{
return fCheckpwHandlerThreadsCnt;
}
return 0;
}
sInt32 ServerControl:: RegisterForNetworkChange ( void )
{
sInt32 scdStatus = eDSNoErr;
CFStringRef dhcpKey = 0; CFStringRef ipKey = 0; CFStringRef niKey = 0; CFStringRef atKey = 0; CFMutableArrayRef notifyKeys = 0;
CFMutableArrayRef notifyPatterns = 0;
Boolean setStatus = FALSE;
CFStringRef aPIDString = 0;
DBGLOG( kLogApplication, "RegisterForNetworkChange(): " );
fSCDStore = SCDynamicStoreCreate(NULL, CFSTR("DirectoryService"), NULL, NULL);
if (fSCDStore != 0)
{
notifyKeys = CFArrayCreateMutable( kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
notifyPatterns = CFArrayCreateMutable( kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
ipKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
CFArrayAppendValue(notifyKeys, ipKey);
CFRelease(ipKey);
dhcpKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetDHCP);
CFArrayAppendValue(notifyPatterns, dhcpKey);
CFRelease(dhcpKey);
atKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetAppleTalk);
CFArrayAppendValue(notifyKeys, atKey);
CFRelease(atKey);
niKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetNetInfo);
CFArrayAppendValue(notifyKeys, niKey);
CFRelease(niKey);
setStatus = SCDynamicStoreSetNotificationKeys(fSCDStore, notifyKeys, notifyPatterns);
CFRelease(notifyKeys);
CFRelease(notifyPatterns);
SCDynamicStoreNotifyCallback( fSCDStore, gServerRunLoop, NetworkChangeCallBack, this );
aPIDString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), (uInt32)getpid());
setStatus = SCDynamicStoreAddTemporaryValue( fSCDStore, CFSTR("DirectoryService:PID"), aPIDString );
CFRelease(aPIDString);
}
return scdStatus;
}
sInt32 ServerControl:: UnRegisterForNetworkChange ( void )
{
sInt32 scdStatus = eDSNoErr;
DBGLOG( kLogApplication, "UnRegisterForNetworkChange(): " );
if (fSCDStore != 0)
{
CFRelease(fSCDStore);
fSCDStore = 0;
}
return scdStatus;
}
sInt32 ServerControl::RegisterForSystemPower ( void )
{
IONotificationPortRef pmNotificationPortRef;
DBGLOG( kLogApplication, "RegisterForSystemPower(): " );
gPMKernelPort = IORegisterForSystemPower(this, &pmNotificationPortRef, dsPMNotificationHandler, &gPMDeregisterNotifier);
if (gPMKernelPort == nil)
{
DBGLOG( kLogApplication, "RegisterForSystemPower(): IORegisterForSystemPower failed" );
}
return (gPMKernelPort != nil) ? eDSNoErr : -1;
}
sInt32 ServerControl::UnRegisterForSystemPower ( void )
{
sInt32 ioResult = eDSNoErr;
DBGLOG( kLogApplication, "UnRegisterForSystemPower(): " );
if (gPMKernelPort != nil) {
gPMKernelPort = nil;
ioResult = (sInt32)IODeregisterForSystemPower(&gPMDeregisterNotifier);
if (ioResult != eDSNoErr)
{
DBGLOG1( kLogApplication, "UnRegisterForSystemPower(): IODeregisterForSystemPower failed, error= %d", ioResult );
}
}
return ioResult;
}
sInt32 ServerControl::HandleNetworkTransition ( void )
{
sInt32 siResult = eDSNoErr;
uInt32 iterator = 0;
CServerPlugin *pPlugin = nil;
sHeader aHeader;
CPlugInList::sTableData *pPIInfo = nil;
CServerPlugin *searchPlugin = nil;
uInt32 searchIterator = 0;
aHeader.fType = kHandleNetworkTransition;
aHeader.fResult = eDSNoErr;
aHeader.fContextData = nil;
SRVRLOG( kLogApplication, "Network transition occurred." );
if ( gPlugins != nil )
{
pPlugin = gPlugins->Next( &iterator );
while (pPlugin != nil)
{
pPIInfo = gPlugins->GetPlugInInfo( iterator-1 );
if (pPIInfo->fState & kActive) {
if ( ::strcmp(pPIInfo->fName,"Search") != 0)
{
siResult = eDSNoErr;
siResult = pPlugin->ProcessRequest( (void*)&aHeader );
if (siResult != eDSNoErr)
{
if (pPIInfo != nil)
{
ERRORLOG2( kLogApplication, "Network transition in %s plugin returned error %d", pPIInfo->fName, siResult );
}
else
{
ERRORLOG1( kLogApplication, "Network transition of unnamed plugin returned error %d", siResult );
}
}
}
else
{
searchIterator = iterator;
searchPlugin = pPlugin;
}
}
pPlugin = gPlugins->Next( &iterator );
}
}
if (searchPlugin != nil)
{
pPIInfo = gPlugins->GetPlugInInfo( searchIterator-1 );
siResult = eDSNoErr;
siResult = searchPlugin->ProcessRequest( (void*)&aHeader );
if (siResult != eDSNoErr)
{
if (pPIInfo != nil)
{
ERRORLOG1( kLogApplication, "Network transition in Search returned error %d", siResult );
}
}
}
return siResult;
}
sInt32 ServerControl::SetUpPeriodicTask ( void )
{
sInt32 siResult = eDSNoErr;
void *ptInfo = nil;
CFRunLoopTimerContext c = {0, (void*)ptInfo, NULL, NULL, PeriodicTaskCopyStringCallback};
CFRunLoopTimerRef timer = CFRunLoopTimerCreate( NULL,
CFAbsoluteTimeGetCurrent() + 120,
120,
0,
0,
DoPeriodicTask,
(CFRunLoopTimerContext*)&c);
CFRunLoopAddTimer(gServerRunLoop, timer, kCFRunLoopDefaultMode);
if (timer) CFRelease(timer);
return siResult;
}
void DoPeriodicTask(CFRunLoopTimerRef timer, void *info)
{
sInt32 siResult = eDSNoErr;
uInt32 iterator = 0;
CServerPlugin *pPlugin = nil;
CPlugInList::sTableData *pPIInfo = nil;
if ( gPlugins != nil )
{
pPlugin = gPlugins->Next( &iterator );
while (pPlugin != nil)
{
pPIInfo = gPlugins->GetPlugInInfo( iterator-1 );
siResult = eDSNoErr;
siResult = pPlugin->PeriodicTask();
if (siResult != eDSNoErr)
{
if (pPIInfo != nil)
{
DBGLOG2( kLogApplication, "Periodic Task in %s plugin returned error %d", pPIInfo->fName, siResult );
}
else
{
DBGLOG1( kLogApplication, "Periodic Task of unnamed plugin returned error %d", siResult );
}
}
pPlugin = gPlugins->Next( &iterator );
}
}
return;
}