/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Modification History * * June 1, 2001 Allan Nathanson * - initial revision */ #include #include #include #include #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ 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; } /* * "context" argument for removeOldKey() and addNewKey() */ typedef struct { SCDynamicStoreRef store; CFArrayRef newKeys; /* for removeOldKey */ 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)) { /* the old notification key is not being retained, remove it */ 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)) { /* add pattern to this sessions notifier list */ myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, TRUE); } } else { if (!CFSetContainsValue(storePrivate->keys, newKey)) { /* add key to this sessions notifier list */ 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) { /* sorry, you must provide a session */ _SCErrorSet(kSCStatusNoStoreSession); return FALSE; } if (storePrivate->server == MACH_PORT_NULL) { /* sorry, you must have an open session to play */ _SCErrorSet(kSCStatusNoStoreServer); return FALSE; } myContext.ok = TRUE; myContext.store = store; /* remove any previously registered keys */ myContext.newKeys = keys; myContext.isRegex = FALSE; my_CFSetApplyFunction(storePrivate->keys, removeOldKey, &myContext); /* register any new keys */ if (keys) { CFArrayApplyFunction(keys, CFRangeMake(0, CFArrayGetCount(keys)), addNewKey, &myContext); } /* remove any previously registered patterns */ myContext.newKeys = patterns; myContext.isRegex = TRUE; my_CFSetApplyFunction(storePrivate->reKeys, removeOldKey, &myContext); /* register any new patterns */ if (patterns) { CFArrayApplyFunction(patterns, CFRangeMake(0, CFArrayGetCount(patterns)), addNewKey, &myContext); } return myContext.ok; }