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