SCDNotifierSetKeys.c [plain text]
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
#include "SCDynamicStoreInternal.h"
#include "config.h"
static __inline__ void
my_CFSetApplyFunction(CFSetRef theSet,
CFSetApplierFunction applier,
void *context)
{
CFAllocatorRef myAllocator;
CFSetRef mySet;
myAllocator = CFGetAllocator(theSet);
mySet = CFSetCreateCopy(myAllocator, theSet);
CFSetApplyFunction(mySet, applier, context);
CFRelease(mySet);
return;
}
typedef struct {
SCDynamicStoreRef store;
CFArrayRef newKeys;
Boolean isRegex;
Boolean ok;
} updateKeysContext, *updateKeysContextRef;
static void
removeOldKey(const void *value, void *context)
{
CFStringRef oldKey = (CFStringRef)value;
updateKeysContextRef myContextRef = (updateKeysContextRef)context;
if (!myContextRef->ok) {
return;
}
if (!myContextRef->newKeys ||
!CFArrayContainsValue(myContextRef->newKeys,
CFRangeMake(0, CFArrayGetCount(myContextRef->newKeys)),
oldKey)) {
myContextRef->ok = SCDynamicStoreRemoveWatchedKey(myContextRef->store,
oldKey,
myContextRef->isRegex);
}
return;
}
static void
addNewKey(const void *value, void *context)
{
CFStringRef newKey = (CFStringRef)value;
updateKeysContextRef myContextRef = (updateKeysContextRef)context;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)myContextRef->store;
if (!myContextRef->ok) {
return;
}
if (myContextRef->isRegex) {
if (!CFSetContainsValue(storePrivate->reKeys, newKey)) {
myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, TRUE);
}
} else {
if (!CFSetContainsValue(storePrivate->keys, newKey)) {
myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, FALSE);
}
}
return;
}
Boolean
SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store,
CFArrayRef keys,
CFArrayRef patterns)
{
updateKeysContext myContext;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSetNotificationKeys:"));
SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" keys = %@"), keys);
SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
if (!store) {
_SCErrorSet(kSCStatusNoStoreSession);
return FALSE;
}
if (storePrivate->server == MACH_PORT_NULL) {
_SCErrorSet(kSCStatusNoStoreServer);
return FALSE;
}
myContext.ok = TRUE;
myContext.store = store;
myContext.newKeys = keys;
myContext.isRegex = FALSE;
my_CFSetApplyFunction(storePrivate->keys, removeOldKey, &myContext);
if (keys) {
CFArrayApplyFunction(keys,
CFRangeMake(0, CFArrayGetCount(keys)),
addNewKey,
&myContext);
}
myContext.newKeys = patterns;
myContext.isRegex = TRUE;
my_CFSetApplyFunction(storePrivate->reKeys, removeOldKey, &myContext);
if (patterns) {
CFArrayApplyFunction(patterns,
CFRangeMake(0, CFArrayGetCount(patterns)),
addNewKey,
&myContext);
}
return myContext.ok;
}