]> git.saurik.com Git - apple/configd.git/blob - Plugins/SimulatorSupport/simulator_support.c
configd-963.250.1.tar.gz
[apple/configd.git] / Plugins / SimulatorSupport / simulator_support.c
1 /*
2 * Copyright (c) 2013, 2015-2018 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 <TargetConditionals.h>
33 #include <SystemConfiguration/SystemConfiguration.h>
34 #include <SystemConfiguration/SCPrivate.h>
35 #include <SystemConfiguration/SCValidation.h>
36
37 #include <dns_sd.h>
38 #include <dns_sd_private.h>
39
40 #include "cache.h"
41
42 #if TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC
43
44
45 static CFMutableArrayRef mirror_keys = NULL;
46 static CFMutableArrayRef mirror_patterns = NULL;
47 static SCDynamicStoreRef store_host = NULL;
48 static SCDynamicStoreRef store_sim = NULL;
49
50
51 #pragma mark -
52 #pragma mark Logging
53
54
55 /*
56 * Logging
57 */
58 __private_extern__ os_log_t
59 __log_SimulatorSupport(void)
60 {
61 static os_log_t log = NULL;
62
63 if (log == NULL) {
64 log = os_log_create("com.apple.SystemConfiguration", "SimulatorSupport");
65 }
66
67 return log;
68 }
69
70
71 #pragma mark -
72 #pragma mark iOS Simulator Support
73
74
75 static void
76 mirror(SCDynamicStoreRef store, CFArrayRef changes, void *info)
77 {
78 #pragma unused(store)
79 CFDictionaryRef content_host;
80 CFDictionaryRef content_sim;
81 CFIndex i;
82 CFIndex n;
83
84 n = CFArrayGetCount(changes);
85 if (n == 0) {
86 // if no changes
87 return;
88 }
89
90 // capture "host" content
91 if (info == NULL) {
92 content_host = SCDynamicStoreCopyMultiple(store_host, changes, NULL);
93 } else {
94 content_host = (CFDictionaryRef)info;
95 }
96
97 // capture [current] "sim" content
98 content_sim = SCDynamicStoreCopyMultiple(store_sim, changes, NULL);
99
100 // update
101 cache_open();
102 for (i = 0; i < n; i++) {
103 CFStringRef key;
104 CFPropertyListRef val;
105
106 key = CFArrayGetValueAtIndex(changes, i);
107 val = (content_host != NULL) ? CFDictionaryGetValue(content_host, key) : NULL;
108 if (val != NULL) {
109 // if "host" content changed
110 cache_SCDynamicStoreSetValue(store_sim, key, val);
111 } else {
112 // if no "host" content
113 val = (content_sim != NULL) ? CFDictionaryGetValue(content_sim, key) : NULL;
114 if (val != NULL) {
115 // if we need to remove the "sim" content
116 cache_SCDynamicStoreRemoveValue(store_sim, key);
117 } else {
118 // if no "sim" content to remove, just notify
119 cache_SCDynamicStoreNotifyValue(store_sim, key);
120 }
121 }
122 }
123 cache_write(store_sim);
124 cache_close();
125
126 // cleanup
127 if ((info == NULL) && (content_host != NULL)) {
128 CFRelease(content_host);
129 }
130 if (content_sim != NULL) {
131 CFRelease(content_sim);
132 }
133
134 return;
135 }
136
137
138 static void
139 mirror_setup()
140 {
141 CFStringRef key;
142 CFStringRef pattern;
143
144 mirror_keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
145 mirror_patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
146
147 // Plugin:InterfaceNamer
148 key = SCDynamicStoreKeyCreate(NULL,
149 CFSTR("%@" "InterfaceNamer"),
150 kSCDynamicStoreDomainPlugin);
151 CFArrayAppendValue(mirror_keys, key);
152 CFRelease(key);
153
154 // Setup:/System
155 // key = SCDynamicStoreKeyCreateComputerName(NULL);
156 // CFArrayAppendValue(mirror_keys, key);
157 // CFRelease(key);
158
159 // Setup:/Network
160 // key = SCDynamicStoreKeyCreateHostNames(NULL);
161 // CFArrayAppendValue(mirror_keys, key);
162 // CFRelease(key);
163
164 // Setup:/Network/Global/.*
165 pattern = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
166 kSCDynamicStoreDomainSetup,
167 kSCCompAnyRegex);
168 CFArrayAppendValue(mirror_patterns, pattern);
169 CFRelease(pattern);
170
171 // Setup:/Network/Service/.*
172 // State:/Network/Service/.*
173 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
174 kSCCompAnyRegex,
175 CFSTR(".*"),
176 NULL);
177 CFArrayAppendValue(mirror_patterns, pattern);
178 CFRelease(pattern);
179
180 // Setup:/Network/Interface/.*
181 // State:/Network/Interface/.*
182 pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
183 kSCCompAnyRegex,
184 CFSTR(".*"),
185 NULL);
186 CFArrayAppendValue(mirror_patterns, pattern);
187 CFRelease(pattern);
188
189 // State:/Network/MulticastDNS
190 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
191 kSCDynamicStoreDomainState,
192 kSCCompNetwork,
193 CFSTR(kDNSServiceCompMulticastDNS));
194 CFArrayAppendValue(mirror_keys, key);
195 CFRelease(key);
196
197 // State:/Network/PrivateDNS
198 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
199 kSCDynamicStoreDomainState,
200 kSCCompNetwork,
201 CFSTR(kDNSServiceCompPrivateDNS));
202 CFArrayAppendValue(mirror_keys, key);
203 CFRelease(key);
204
205 return;
206 }
207
208
209 #define N_QUICK 64
210
211
212 __private_extern__
213 void
214 prime_SimulatorSupport()
215 {
216 CFDictionaryRef content_host;
217 CFIndex n;
218
219 SC_log(LOG_DEBUG, "prime() called");
220
221 // copy current content from base OS store to _Sim store
222 content_host = SCDynamicStoreCopyMultiple(store_host, mirror_keys, mirror_patterns);
223 CFRelease(mirror_keys);
224 mirror_keys = NULL;
225 CFRelease(mirror_patterns);
226 mirror_patterns = NULL;
227
228 if (content_host == NULL) {
229 return;
230 }
231
232 n = CFDictionaryGetCount(content_host);
233 if (n > 0) {
234 CFArrayRef changes;
235 const void * keys_host_q[N_QUICK];
236 const void ** keys_host = keys_host_q;
237
238 if (n > (CFIndex)(sizeof(keys_host_q) / sizeof(CFStringRef))) {
239 keys_host = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
240 }
241
242 CFDictionaryGetKeysAndValues(content_host, keys_host, NULL);
243
244 changes = CFArrayCreate(NULL, keys_host, n, &kCFTypeArrayCallBacks);
245 mirror(store_host, changes, (void *)content_host);
246 CFRelease(changes);
247
248 if (keys_host != keys_host_q) {
249 CFAllocatorDeallocate(NULL, keys_host);
250 }
251 }
252
253 CFRelease(content_host);
254 return;
255 }
256
257
258 __private_extern__
259 void
260 load_SimulatorSupport(CFBundleRef bundle, Boolean bundleVerbose)
261 {
262 #pragma unused(bundleVerbose)
263 Boolean ok;
264 CFMutableDictionaryRef options;
265 CFRunLoopSourceRef rls;
266
267 SC_log(LOG_DEBUG, "load() called");
268 SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle));
269
270 // setup
271 mirror_setup();
272
273 // setup SCDynamicStore mirroring (from "host")
274 options = CFDictionaryCreateMutable(NULL,
275 0,
276 &kCFTypeDictionaryKeyCallBacks,
277 &kCFTypeDictionaryValueCallBacks);
278 CFDictionarySetValue(options, kSCDynamicStoreUseHostServer, kCFBooleanTrue);
279 store_host = SCDynamicStoreCreateWithOptions(NULL,
280 CFSTR("SimulatorSupport(host)"),
281 options,
282 mirror,
283 NULL);
284 CFRelease(options);
285 assert(store_host != NULL);
286
287 ok = SCDynamicStoreSetNotificationKeys(store_host, mirror_keys, mirror_patterns);
288 assert(ok);
289
290 rls = SCDynamicStoreCreateRunLoopSource(NULL, store_host, 0);
291 assert(rls != NULL);
292
293 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
294 CFRelease(rls);
295
296 // setup SCDynamicStore mirroring (to "iOS Simulator")
297 store_sim = SCDynamicStoreCreate(NULL,
298 CFSTR("SimulatorSupport(sim)"),
299 NULL,
300 NULL);
301
302 return;
303 }
304
305
306 #ifdef MAIN
307
308
309 #pragma mark -
310 #pragma mark Standalone test code
311
312
313 int
314 main(int argc, char **argv)
315 {
316 _sc_log = FALSE;
317 _sc_verbose = (argc > 1) ? TRUE : FALSE;
318
319 load_SimulatorSupport(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE);
320 prime_SimulatorSupport();
321 CFRunLoopRun();
322 // not reached
323 exit(0);
324 return 0;
325 }
326 #endif
327
328 #endif // TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC