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