]> git.saurik.com Git - apple/configd.git/blame - Plugins/SimulatorSupport/simulator_support.c
configd-802.40.13.tar.gz
[apple/configd.git] / Plugins / SimulatorSupport / simulator_support.c
CommitLineData
5e9ce69e 1/*
9de8ab86 2 * Copyright (c) 2013, 2015 Apple Inc. All rights reserved.
5e9ce69e
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
9de8ab86 5 *
5e9ce69e
A
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.
9de8ab86 12 *
5e9ce69e
A
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.
9de8ab86 20 *
5e9ce69e
A
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
5e9ce69e
A
47static CFMutableArrayRef mirror_keys = NULL;
48static CFMutableArrayRef mirror_patterns = NULL;
49static SCDynamicStoreRef store_host = NULL;
50static SCDynamicStoreRef store_sim = NULL;
51
52
53#pragma mark -
54#pragma mark iOS Simulator Support
55
56
57static void
58mirror(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
119static void
120mirror_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__
194void
195prime_SimulatorSupport()
196{
197 CFDictionaryRef content_host;
198 CFIndex n;
199
9de8ab86 200 SC_log(LOG_DEBUG, "prime() called");
5e9ce69e
A
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__
240void
241load_SimulatorSupport(CFBundleRef bundle, Boolean bundleVerbose)
242{
243 Boolean ok;
244 CFMutableDictionaryRef options;
245 CFRunLoopSourceRef rls;
246
9de8ab86
A
247 SC_log(LOG_DEBUG, "load() called");
248 SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle));
5e9ce69e
A
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
293int
294main(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