#include <unistd.h>
#include "configd.h"
#include "session.h"
static Boolean
isMySessionKey(CFStringRef sessionKey, CFStringRef key)
{
CFDictionaryRef dict;
CFStringRef storeSessionKey;
dict = CFDictionaryGetValue(storeData, key);
if (!dict) {
return FALSE;
}
storeSessionKey = CFDictionaryGetValue(dict, kSCDSession);
if (!storeSessionKey) {
return FALSE;
}
if (!CFEqual(sessionKey, storeSessionKey)) {
return FALSE;
}
return TRUE;
}
static void
removeAllKeys(SCDynamicStoreRef store, Boolean isRegex)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFArrayRef keys;
CFIndex n;
keys = isRegex ? storePrivate->patterns : storePrivate->keys;
n = (keys != NULL) ? CFArrayGetCount(keys) : 0;
if (n > 0) {
CFIndex i;
CFArrayRef keysToRemove;
keysToRemove = CFArrayCreateCopy(NULL, keys);
for (i = 0; i < n; i++) {
(void) __SCDynamicStoreRemoveWatchedKey(store,
CFArrayGetValueAtIndex(keysToRemove, i),
isRegex,
TRUE);
}
CFRelease(keysToRemove);
}
return;
}
__private_extern__
int
__SCDynamicStoreClose(SCDynamicStoreRef *store)
{
serverSessionRef mySession;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)*store;
SC_trace("close : %5d",
storePrivate->server);
removeAllKeys(*store, FALSE); removeAllKeys(*store, TRUE);
__MACH_PORT_DEBUG(storePrivate->notifyPort != MACH_PORT_NULL, "*** __SCDynamicStoreClose", storePrivate->notifyPort);
(void) __SCDynamicStoreNotifyCancel(*store);
mySession = getSession(storePrivate->server);
if (mySession->sessionKeys != NULL) {
CFIndex n = CFArrayGetCount(mySession->sessionKeys);
Boolean push = FALSE;
CFStringRef sessionKey;
sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
for (CFIndex i = 0; i < n; i++) {
CFStringRef key = CFArrayGetValueAtIndex(mySession->sessionKeys, i);
if (isMySessionKey(sessionKey, key)) {
(void) __SCDynamicStoreRemoveValue(*store, key, TRUE);
push = TRUE;
}
}
CFRelease(sessionKey);
if (push) {
(void) __SCDynamicStorePush();
}
}
storePrivate->server = MACH_PORT_NULL;
CFRelease(*store);
*store = NULL;
return kSCStatusOK;
}