#include <mach/mach.h>
#include <mach/mach_error.h>
#include <servers/bootstrap.h>
#include <SystemConfiguration/SCD.h>
#include "config.h"
#include "SCDPrivate.h"
SCDSessionRef
_SCDSessionCreatePrivate()
{
SCDSessionRef newSession;
SCDSessionPrivateRef newPrivate;
newSession = (SCDSessionRef)CFAllocatorAllocate(NULL, sizeof(SCDSessionPrivate), 0);
newPrivate = (SCDSessionPrivateRef)newSession;
newPrivate->server = MACH_PORT_NULL;
SCDOptionSet(newSession, kSCDOptionDebug, SCDOptionGet(NULL, kSCDOptionDebug ));
SCDOptionSet(newSession, kSCDOptionVerbose, SCDOptionGet(NULL, kSCDOptionVerbose ));
SCDOptionSet(newSession, kSCDOptionIsLocked, FALSE);
SCDOptionSet(newSession, kSCDOptionUseSyslog, SCDOptionGet(NULL, kSCDOptionUseSyslog ));
SCDOptionSet(newSession, kSCDOptionUseCFRunLoop, SCDOptionGet(NULL, kSCDOptionUseCFRunLoop));
newPrivate->keys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
newPrivate->reKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
newPrivate->notifyStatus = NotifierNotRegistered;
newPrivate->callbackFunction = NULL;
newPrivate->callbackArgument = NULL;
newPrivate->callbackPort = NULL;
newPrivate->callbackRunLoopSource = NULL;
newPrivate->callbackHelper = NULL;
newPrivate->notifyPort = MACH_PORT_NULL;
newPrivate->notifyPortIdentifier = 0;
newPrivate->notifyFile = -1;
newPrivate->notifyFileIdentifier = 0;
newPrivate->notifySignal = 0;
newPrivate->notifySignalTask = TASK_NULL;
return newSession;
}
SCDStatus
SCDOpen(SCDSessionRef *session, CFStringRef name)
{
SCDSessionPrivateRef sessionPrivate;
kern_return_t status;
mach_port_t bootstrap_port;
mach_port_t server;
CFDataRef xmlName;
xmlData_t myNameRef;
CFIndex myNameLen;
SCDStatus scd_status;
SCDLog(LOG_DEBUG, CFSTR("SCDOpen:"));
SCDLog(LOG_DEBUG, CFSTR(" name = %@"), name);
sessionPrivate = (SCDSessionPrivateRef)_SCDSessionCreatePrivate();
*session = (SCDSessionRef)sessionPrivate;
status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
if (status != KERN_SUCCESS) {
SCDLog(LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
CFAllocatorDeallocate(NULL, sessionPrivate);
*session = NULL;
return SCD_NOSERVER;
}
status = bootstrap_look_up(bootstrap_port, SCD_SERVER, &server);
switch (status) {
case BOOTSTRAP_SUCCESS :
break;
case BOOTSTRAP_UNKNOWN_SERVICE :
CFAllocatorDeallocate(NULL, sessionPrivate);
*session = NULL;
return SCD_NOSERVER;
break;
default :
#ifdef DEBUG
SCDLog(LOG_DEBUG, CFSTR("bootstrap_status: %s"), mach_error_string(status));
#endif
CFAllocatorDeallocate(NULL, sessionPrivate);
*session = NULL;
return SCD_NOSERVER;
}
xmlName = CFPropertyListCreateXMLData(NULL, name);
myNameRef = (xmlData_t)CFDataGetBytePtr(xmlName);
myNameLen = CFDataGetLength(xmlName);
status = configopen(server, myNameRef, myNameLen, &sessionPrivate->server, (int *)&scd_status);
CFRelease(xmlName);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
SCDLog(LOG_DEBUG, CFSTR("configopen(): %s"), mach_error_string(status));
CFAllocatorDeallocate(NULL, sessionPrivate);
*session = NULL;
return SCD_NOSERVER;
}
SCDLog(LOG_DEBUG, CFSTR(" server port = %d"), sessionPrivate->server);
return scd_status;
}