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