#include "configd.h"
#include "configd_server.h"
#include "session.h"
__private_extern__
int
__SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
{
if (_configd_verbose) {
SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
}
*store = (SCDynamicStoreRef)__SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
if (storeData == NULL) {
sessionData = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
storeData = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
patternData = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
changedKeys = CFSetCreateMutable(NULL,
0,
&kCFTypeSetCallBacks);
deferredRemovals = CFSetCreateMutable(NULL,
0,
&kCFTypeSetCallBacks);
removedSessionKeys = CFSetCreateMutable(NULL,
0,
&kCFTypeSetCallBacks);
}
return kSCStatusOK;
}
__private_extern__
kern_return_t
_configopen(mach_port_t server,
xmlData_t nameRef,
mach_msg_type_number_t nameLen,
mach_port_t *newServer,
int *sc_status)
{
kern_return_t status;
serverSessionRef mySession, newSession;
CFStringRef name;
mach_port_t oldNotify;
CFStringRef sessionKey;
CFDictionaryRef info;
CFMutableDictionaryRef newInfo;
CFMachPortRef mp;
if (_configd_verbose) {
SCLog(TRUE, LOG_DEBUG, CFSTR("Open new session."));
SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
}
if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(name)) {
CFRelease(name);
*sc_status = kSCStatusInvalidArgument;
return KERN_SUCCESS;
}
mySession = getSession(server);
if (mySession->store) {
CFRelease(name);
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" Sorry, this session is already open."));
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
mp = CFMachPortCreate(NULL, configdCallback, NULL, NULL);
*newServer = CFMachPortGetPort(mp);
newSession = addSession(mp);
newSession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mp, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
newSession->serverRunLoopSource,
kCFRunLoopDefaultMode);
newSession->callerEUID = mySession->callerEUID;
newSession->callerEGID = mySession->callerEGID;
if (_configd_trace) {
SCTrace(TRUE, _configd_trace, CFSTR("open : %5d : %@\n"), *newServer, name);
}
*sc_status = __SCDynamicStoreOpen(&newSession->store, name);
((SCDynamicStorePrivateRef)newSession->store)->server = *newServer;
status = mach_port_request_notification(mach_task_self(),
*newServer,
MACH_NOTIFY_NO_SENDERS,
1,
*newServer,
MACH_MSG_TYPE_MAKE_SEND_ONCE,
&oldNotify);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
CFRelease(name);
cleanupSession(*newServer);
*newServer = MACH_PORT_NULL;
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (oldNotify != MACH_PORT_NULL) {
SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
}
sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer);
info = CFDictionaryGetValue(sessionData, sessionKey);
if (info) {
newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
} else {
newInfo = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
CFDictionarySetValue(newInfo, kSCDName, name);
CFRelease(name);
CFDictionarySetValue(sessionData, sessionKey, newInfo);
CFRelease(newInfo);
CFRelease(sessionKey);
return KERN_SUCCESS;
}