]> git.saurik.com Git - apple/configd.git/blob - Plugins/SimulatorSupport/simulator_support.c
configd-801.10.2.tar.gz
[apple/configd.git] / Plugins / SimulatorSupport / simulator_support.c
1 /*
2 * Copyright (c) 2013, 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * March 15, 2013 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include <SystemConfiguration/SystemConfiguration.h>
33 #include <SystemConfiguration/SCPrivate.h>
34 #include <SystemConfiguration/SCValidation.h>
35
36 #include <dns_sd.h>
37 #ifndef kDNSServiceCompMulticastDNS
38 #define kDNSServiceCompMulticastDNS "MulticastDNS"
39 #endif
40 #ifndef kDNSServiceCompPrivateDNS
41 #define kDNSServiceCompPrivateDNS "PrivateDNS"
42 #endif
43
44 #include "cache.h"
45
46
47 static CFMutableArrayRef mirror_keys = NULL;
48 static CFMutableArrayRef mirror_patterns = NULL;
49 static SCDynamicStoreRef store_host = NULL;
50 static SCDynamicStoreRef store_sim = NULL;
51
52
53 #pragma mark -
54 #pragma mark iOS Simulator Support
55
56
57 static void
58 mirror(SCDynamicStoreRef store, CFArrayRef changes, void *info)
59 {
60 CFDictionaryRef content_host;
61 CFDictionaryRef content_sim;
62 CFIndex i;
63 CFIndex n;
64
65 n = CFArrayGetCount(changes);
66 if (n == 0) {
67 // if no changes
68 return;
69 }
70
71 // capture "host" content
72 if (info == NULL) {
73 content_host = SCDynamicStoreCopyMultiple(store_host, changes, NULL);
74 } else {
75 content_host = (CFDictionaryRef)info;
76 }
77
78 // capture [current] "sim" content
79 content_sim = SCDynamicStoreCopyMultiple(store_sim, changes, NULL);
80
81 // update
82 cache_open();
83 for (i = 0; i < n; i++) {
84 CFStringRef key;
85 CFPropertyListRef val;
86
87 key = CFArrayGetValueAtIndex(changes, i);
88 val = (content_host != NULL) ? CFDictionaryGetValue(content_host, key) : NULL;
89 if (val != NULL) {
90 // if "host" content changed
91 cache_SCDynamicStoreSetValue(store_sim, key, val);
92 } else {
93 // if no "host" content
94 val = (content_sim != NULL) ? CFDictionaryGetValue(content_sim, key) : NULL;
95 if (val != NULL) {
96 // if we need to remove the "sim" content
97 cache_SCDynamicStoreRemoveValue(store_sim, key);
98 } else {
99 // if no "sim" content to remove, just notify
100 cache_SCDynamicStoreNotifyValue(store_sim, key);
101 }
102 }
103 }
104 cache_write(store_sim);
105 cache_close();
106
107 // cleanup
108 if ((info == NULL) && (content_host != NULL)) {
109 CFRelease(content_host);
110 }
111 if (content_sim != NULL) {
112 CFRelease(content_sim);
113 }
114
115 return;
116 }
117
118
119 static void
120 mirror_setup()
121 {
122 CFStringRef key;
123 CFStringRef pattern;
124
125 mirror_keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
126 mirror_patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
127
128 // Plugin:InterfaceNamer
129 key = SCDynamicStoreKeyCreate(NULL,
130 CFSTR("%@" "InterfaceNamer"),
131 kSCDynamicStoreDomainPlugin);
132 CFArrayAppendValue(mirror_keys, key);
133 CFRelease(key);
134
135 // Setup:/System
136 // key = SCDynamicStoreKeyCreateComputerName(NULL);
137 // CFArrayAppendValue(mirror_keys, key);
138 // CFRelease(key);
139
140 // Setup:/Network
141 // key = SCDynamicStoreKeyCreateHostNames(NULL);
142 // CFArrayAppendValue(mirror_keys, key);
143 // CFRelease(key);
144
145 // Setup:/Network/Global/.*
146 pattern = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
147 kSCDynamicStoreDomainSetup,
148 kSCCompAnyRegex);
149 CFArrayAppendValue(mirror_patterns, pattern);
150 CFRelease(pattern);
151
152 // Setup:/Network/Service/.*
153 // State:/Network/Service/.*
154 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
155 kSCCompAnyRegex,
156 CFSTR(".*"),
157 NULL);
158 CFArrayAppendValue(mirror_patterns, pattern);
159 CFRelease(pattern);
160
161 // Setup:/Network/Interface/.*
162 // State:/Network/Interface/.*
163 pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
164 kSCCompAnyRegex,
165 CFSTR(".*"),
166 NULL);
167 CFArrayAppendValue(mirror_patterns, pattern);
168 CFRelease(pattern);
169
170 // State:/Network/MulticastDNS
171 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
172 kSCDynamicStoreDomainState,
173 kSCCompNetwork,
174 CFSTR(kDNSServiceCompMulticastDNS));
175 CFArrayAppendValue(mirror_keys, key);
176 CFRelease(key);
177
178 // State:/Network/PrivateDNS
179 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
180 kSCDynamicStoreDomainState,
181 kSCCompNetwork,
182 CFSTR(kDNSServiceCompPrivateDNS));
183 CFArrayAppendValue(mirror_keys, key);
184 CFRelease(key);
185
186 return;
187 }
188
189
190 #define N_QUICK 64
191
192
193 __private_extern__
194 void
195 prime_SimulatorSupport()
196 {
197 CFDictionaryRef content_host;
198 CFIndex n;
199
200 SC_log(LOG_DEBUG, "prime() called");
201
202 // copy current content from base OS store to _Sim store
203 content_host = SCDynamicStoreCopyMultiple(store_host, mirror_keys, mirror_patterns);
204 CFRelease(mirror_keys);
205 mirror_keys = NULL;
206 CFRelease(mirror_patterns);
207 mirror_patterns = NULL;
208
209 if (content_host == NULL) {
210 return;
211 }
212
213 n = CFDictionaryGetCount(content_host);
214 if (n > 0) {
215 CFArrayRef changes;
216 const void * keys_host_q[N_QUICK];
217 const void ** keys_host = keys_host_q;
218
219 if (n > (CFIndex)(sizeof(keys_host_q) / sizeof(CFStringRef))) {
220 keys_host = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
221 }
222
223 CFDictionaryGetKeysAndValues(content_host, keys_host, NULL);
224
225 changes = CFArrayCreate(NULL, keys_host, n, &kCFTypeArrayCallBacks);
226 mirror(store_host, changes, (void *)content_host);
227 CFRelease(changes);
228
229 if (keys_host != keys_host_q) {
230 CFAllocatorDeallocate(NULL, keys_host);
231 }
232 }
233
234 CFRelease(content_host);
235 return;
236 }
237
238
239 __private_extern__
240 void
241 load_SimulatorSupport(CFBundleRef bundle, Boolean bundleVerbose)
242 {
243 Boolean ok;
244 CFMutableDictionaryRef options;
245 CFRunLoopSourceRef rls;
246
247 SC_log(LOG_DEBUG, "load() called");
248 SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle));
249
250 // setup
251 mirror_setup();
252
253 // setup SCDynamicStore mirroring (from "host")
254 options = CFDictionaryCreateMutable(NULL,
255 0,
256 &kCFTypeDictionaryKeyCallBacks,
257 &kCFTypeDictionaryValueCallBacks);
258 CFDictionarySetValue(options, kSCDynamicStoreUseHostServer, kCFBooleanTrue);
259 store_host = SCDynamicStoreCreateWithOptions(NULL,
260 CFSTR("SimulatorSupport(host)"),
261 options,
262 mirror,
263 NULL);
264 CFRelease(options);
265 assert(store_host != NULL);
266
267 ok = SCDynamicStoreSetNotificationKeys(store_host, mirror_keys, mirror_patterns);
268 assert(ok);
269
270 rls = SCDynamicStoreCreateRunLoopSource(NULL, store_host, 0);
271 assert(rls != NULL);
272
273 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
274 CFRelease(rls);
275
276 // setup SCDynamicStore mirroring (to "iOS Simulator")
277 store_sim = SCDynamicStoreCreate(NULL,
278 CFSTR("SimulatorSupport(sim)"),
279 NULL,
280 NULL);
281
282 return;
283 }
284
285
286 #ifdef MAIN
287
288
289 #pragma mark -
290 #pragma mark Standalone test code
291
292
293 int
294 main(int argc, char **argv)
295 {
296 _sc_log = FALSE;
297 _sc_verbose = (argc > 1) ? TRUE : FALSE;
298
299 load_SimulatorSupport(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE);
300 prime_SimulatorSupport();
301 CFRunLoopRun();
302 // not reached
303 exit(0);
304 return 0;
305 }
306 #endif