]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCDNotifierSetKeys.c
configd-42.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDNotifierSetKeys.c
diff --git a/SystemConfiguration.fproj/SCDNotifierSetKeys.c b/SystemConfiguration.fproj/SCDNotifierSetKeys.c
new file mode 100644 (file)
index 0000000..f504f7c
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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 <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#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;
+}