#include "configd.h"
__private_extern__ CFMutableDictionaryRef sessionData = NULL;
__private_extern__ CFMutableDictionaryRef storeData = NULL;
__private_extern__ CFMutableDictionaryRef storeData_s = NULL;
__private_extern__ CFMutableDictionaryRef patternData = NULL;
__private_extern__ CFMutableDictionaryRef patternData_s = NULL;
__private_extern__ CFMutableSetRef changedKeys = NULL;
__private_extern__ CFMutableSetRef changedKeys_s = NULL;
__private_extern__ CFMutableSetRef deferredRemovals = NULL;
__private_extern__ CFMutableSetRef deferredRemovals_s = NULL;
__private_extern__ CFMutableSetRef removedSessionKeys = NULL;
__private_extern__ CFMutableSetRef removedSessionKeys_s = NULL;
__private_extern__ CFMutableSetRef needsNotification = NULL;
__private_extern__ int storeLocked = 0;
__private_extern__
void
_swapLockedStoreData()
{
void *temp;
temp = storeData;
storeData = storeData_s;
storeData_s = temp;
temp = patternData;
patternData = patternData_s;
patternData_s = temp;
temp = changedKeys;
changedKeys = changedKeys_s;
changedKeys_s = temp;
temp = deferredRemovals;
deferredRemovals = deferredRemovals_s;
deferredRemovals_s = temp;
temp = removedSessionKeys;
removedSessionKeys = removedSessionKeys_s;
removedSessionKeys_s = temp;
return;
}
__private_extern__
void
_addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
{
CFDictionaryRef dict;
CFMutableDictionaryRef newDict;
CFArrayRef watchers;
CFMutableArrayRef newWatchers;
CFArrayRef watcherRefs;
CFMutableArrayRef newWatcherRefs;
CFIndex i;
int refCnt;
CFNumberRef refNum;
dict = CFDictionaryGetValue(storeData, watchedKey);
if (dict) {
newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
} else {
newDict = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
watchers = CFDictionaryGetValue(newDict, kSCDWatchers);
watcherRefs = CFDictionaryGetValue(newDict, kSCDWatcherRefs);
if (watchers) {
newWatchers = CFArrayCreateMutableCopy(NULL, 0, watchers);
newWatcherRefs = CFArrayCreateMutableCopy(NULL, 0, watcherRefs);
} else {
newWatchers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
newWatcherRefs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
}
i = CFArrayGetFirstIndexOfValue(newWatchers,
CFRangeMake(0, CFArrayGetCount(newWatchers)),
sessionNum);
if (i == -1) {
CFArrayAppendValue(newWatchers, sessionNum);
refCnt = 1;
refNum = CFNumberCreate(NULL, kCFNumberIntType, &refCnt);
CFArrayAppendValue(newWatcherRefs, refNum);
CFRelease(refNum);
} else {
refNum = CFArrayGetValueAtIndex(newWatcherRefs, i);
CFNumberGetValue(refNum, kCFNumberIntType, &refCnt);
refCnt++;
refNum = CFNumberCreate(NULL, kCFNumberIntType, &refCnt);
CFArraySetValueAtIndex(newWatcherRefs, i, refNum);
CFRelease(refNum);
}
CFDictionarySetValue(newDict, kSCDWatchers, newWatchers);
CFRelease(newWatchers);
CFDictionarySetValue(newDict, kSCDWatcherRefs, newWatcherRefs);
CFRelease(newWatcherRefs);
CFDictionarySetValue(storeData, watchedKey, newDict);
CFRelease(newDict);
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" _addWatcher: %@, %@"), sessionNum, watchedKey);
return;
}
__private_extern__
void
_removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
{
CFDictionaryRef dict;
CFMutableDictionaryRef newDict;
CFArrayRef watchers;
CFMutableArrayRef newWatchers;
CFArrayRef watcherRefs;
CFMutableArrayRef newWatcherRefs;
CFIndex i;
int refCnt;
CFNumberRef refNum;
dict = CFDictionaryGetValue(storeData, watchedKey);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" _removeWatcher: %@, %@, key not watched"), sessionNum, watchedKey);
return;
}
newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
watchers = CFDictionaryGetValue(newDict, kSCDWatchers);
newWatchers = CFArrayCreateMutableCopy(NULL, 0, watchers);
watcherRefs = CFDictionaryGetValue(newDict, kSCDWatcherRefs);
newWatcherRefs = CFArrayCreateMutableCopy(NULL, 0, watcherRefs);
i = CFArrayGetFirstIndexOfValue(newWatchers,
CFRangeMake(0, CFArrayGetCount(newWatchers)),
sessionNum);
if (i == -1) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" _removeWatcher: %@, %@, session not watching"), sessionNum, watchedKey);
CFRelease(newDict);
CFRelease(newWatchers);
CFRelease(newWatcherRefs);
return;
}
refNum = CFArrayGetValueAtIndex(newWatcherRefs, i);
CFNumberGetValue(refNum, kCFNumberIntType, &refCnt);
if (--refCnt > 0) {
refNum = CFNumberCreate(NULL, kCFNumberIntType, &refCnt);
CFArraySetValueAtIndex(newWatcherRefs, i, refNum);
CFRelease(refNum);
} else {
CFArrayRemoveValueAtIndex(newWatchers, i);
CFArrayRemoveValueAtIndex(newWatcherRefs, i);
}
if (CFArrayGetCount(newWatchers) > 0) {
CFDictionarySetValue(newDict, kSCDWatchers, newWatchers);
CFDictionarySetValue(newDict, kSCDWatcherRefs, newWatcherRefs);
} else {
CFDictionaryRemoveValue(newDict, kSCDWatchers);
CFDictionaryRemoveValue(newDict, kSCDWatcherRefs);
}
CFRelease(newWatchers);
CFRelease(newWatcherRefs);
if (CFDictionaryGetCount(newDict) > 0) {
CFDictionarySetValue(storeData, watchedKey, newDict);
} else {
CFDictionaryRemoveValue(storeData, watchedKey);
}
CFRelease(newDict);
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" _removeWatcher: %@, %@"), sessionNum, watchedKey);
return;
}