]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCDNotifierSetKeys.c
configd-53.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDNotifierSetKeys.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /*
24 * Modification History
25 *
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - initial revision
28 */
29
30 #include <mach/mach.h>
31 #include <mach/mach_error.h>
32
33 #include <SystemConfiguration/SystemConfiguration.h>
34 #include <SystemConfiguration/SCPrivate.h>
35 #include "SCDynamicStoreInternal.h"
36 #include "config.h" /* MiG generated file */
37
38
39 static __inline__ void
40 my_CFSetApplyFunction(CFSetRef theSet,
41 CFSetApplierFunction applier,
42 void *context)
43 {
44 CFAllocatorRef myAllocator;
45 CFSetRef mySet;
46
47 myAllocator = CFGetAllocator(theSet);
48 mySet = CFSetCreateCopy(myAllocator, theSet);
49 CFSetApplyFunction(mySet, applier, context);
50 CFRelease(mySet);
51 return;
52 }
53
54
55 /*
56 * "context" argument for removeOldKey() and addNewKey()
57 */
58 typedef struct {
59 SCDynamicStoreRef store;
60 CFArrayRef newKeys; /* for removeOldKey */
61 Boolean isRegex;
62 Boolean ok;
63 } updateKeysContext, *updateKeysContextRef;
64
65
66 static void
67 removeOldKey(const void *value, void *context)
68 {
69 CFStringRef oldKey = (CFStringRef)value;
70 updateKeysContextRef myContextRef = (updateKeysContextRef)context;
71
72 if (!myContextRef->ok) {
73 return;
74 }
75
76 if (!myContextRef->newKeys ||
77 !CFArrayContainsValue(myContextRef->newKeys,
78 CFRangeMake(0, CFArrayGetCount(myContextRef->newKeys)),
79 oldKey)) {
80 /* the old notification key is not being retained, remove it */
81 myContextRef->ok = SCDynamicStoreRemoveWatchedKey(myContextRef->store,
82 oldKey,
83 myContextRef->isRegex);
84 }
85
86 return;
87 }
88
89
90 static void
91 addNewKey(const void *value, void *context)
92 {
93 CFStringRef newKey = (CFStringRef)value;
94 updateKeysContextRef myContextRef = (updateKeysContextRef)context;
95 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)myContextRef->store;
96
97 if (!myContextRef->ok) {
98 return;
99 }
100
101 if (myContextRef->isRegex) {
102 if (!CFSetContainsValue(storePrivate->reKeys, newKey)) {
103 /* add pattern to this sessions notifier list */
104 myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, TRUE);
105 }
106 } else {
107 if (!CFSetContainsValue(storePrivate->keys, newKey)) {
108 /* add key to this sessions notifier list */
109 myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, FALSE);
110 }
111 }
112
113 return;
114 }
115
116 Boolean
117 SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store,
118 CFArrayRef keys,
119 CFArrayRef patterns)
120 {
121 updateKeysContext myContext;
122 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
123
124 SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSetNotificationKeys:"));
125 SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" keys = %@"), keys);
126 SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
127
128 if (!store) {
129 /* sorry, you must provide a session */
130 _SCErrorSet(kSCStatusNoStoreSession);
131 return FALSE;
132 }
133
134 if (storePrivate->server == MACH_PORT_NULL) {
135 /* sorry, you must have an open session to play */
136 _SCErrorSet(kSCStatusNoStoreServer);
137 return FALSE;
138 }
139
140 myContext.ok = TRUE;
141 myContext.store = store;
142
143 /* remove any previously registered keys */
144 myContext.newKeys = keys;
145 myContext.isRegex = FALSE;
146 my_CFSetApplyFunction(storePrivate->keys, removeOldKey, &myContext);
147
148 /* register any new keys */
149 if (keys) {
150 CFArrayApplyFunction(keys,
151 CFRangeMake(0, CFArrayGetCount(keys)),
152 addNewKey,
153 &myContext);
154 }
155
156 /* remove any previously registered patterns */
157 myContext.newKeys = patterns;
158 myContext.isRegex = TRUE;
159 my_CFSetApplyFunction(storePrivate->reKeys, removeOldKey, &myContext);
160
161 /* register any new patterns */
162 if (patterns) {
163 CFArrayApplyFunction(patterns,
164 CFRangeMake(0, CFArrayGetCount(patterns)),
165 addNewKey,
166 &myContext);
167 }
168
169 return myContext.ok;
170 }