]> git.saurik.com Git - apple/configd.git/blob - Plugins/common/IPMonitorControlPrefs.c
configd-963.tar.gz
[apple/configd.git] / Plugins / common / IPMonitorControlPrefs.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 * IPMonitorControlPrefs.c
26 * - definitions for accessing IPMonitor control preferences
27 */
28
29 /*
30 * Modification History
31 *
32 * January 14, 2013 Dieter Siegmund (dieter@apple)
33 * - created
34 */
35
36 #include <TargetConditionals.h>
37 #include <SystemConfiguration/SCPreferences.h>
38 #include <SystemConfiguration/SCPrivate.h>
39 #include <SystemConfiguration/scprefs_observer.h>
40 #include "IPMonitorControlPrefs.h"
41
42 os_log_t __log_IPMonitor();
43
44 /*
45 * kIPMonitorControlPrefsID
46 * - identifies the IPMonitor preferences file that contains 'Verbose'
47 */
48 #define kIPMonitorControlPrefsIDStr "com.apple.IPMonitor.control.plist"
49 #define kIPMonitorControlPrefsID CFSTR(kIPMonitorControlPrefsIDStr)
50
51 /*
52 * kVerbose
53 * - indicates whether IPMonitor is verbose or not
54 */
55 #define kVerbose CFSTR("Verbose")
56
57 static SCPreferencesRef S_prefs;
58 static IPMonitorControlPrefsCallBack S_callback;
59
60 static SCPreferencesRef
61 IPMonitorControlPrefsGet(void)
62 {
63 if (S_prefs == NULL) {
64 IPMonitorControlPrefsInit(NULL, NULL);
65 }
66 return (S_prefs);
67 }
68
69 static void
70 prefs_changed(void * arg)
71 {
72 #pragma unused(arg)
73 os_activity_t activity;
74
75 activity = os_activity_create("processing IPMonitor [rank] preference change",
76 OS_ACTIVITY_CURRENT,
77 OS_ACTIVITY_FLAG_DEFAULT);
78 os_activity_scope(activity);
79
80 /* get the current value */
81 if (S_callback != NULL) {
82 (*S_callback)(S_prefs);
83 }
84
85 os_release(activity);
86
87 return;
88 }
89
90 #if TARGET_OS_IPHONE
91 /*
92 * kIPMonitorControlManangedPrefsID
93 * - identifies the location of the managed preferences file
94 */
95 #define kManagedPrefsDirStr "/Library/Managed Preferences/mobile/"
96 #define kIPMonitorControlManagedPrefsID CFSTR(kManagedPrefsDirStr \
97 kIPMonitorControlPrefsIDStr)
98 static SCPreferencesRef S_managed_prefs;
99
100 static SCPreferencesRef
101 IPMonitorControlManagedPrefsGet(void)
102 {
103 if (S_managed_prefs == NULL) {
104 S_managed_prefs
105 = SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
106 kIPMonitorControlManagedPrefsID);
107 }
108 return (S_managed_prefs);
109 }
110
111 static void
112 enable_prefs_observer(CFRunLoopRef runloop)
113 {
114 CFRunLoopSourceContext context;
115 dispatch_block_t handler;
116 dispatch_queue_t queue;
117 CFRunLoopSourceRef source;
118
119 bzero(&context, sizeof(context));
120 context.perform = prefs_changed;
121 source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
122 CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes);
123 queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
124 handler = ^{
125 if (source != NULL) {
126 CFRunLoopSourceSignal(source);
127 if (runloop != NULL) {
128 CFRunLoopWakeUp(runloop);
129 }
130 };
131 };
132 _scprefs_observer_watch(scprefs_observer_type_global,
133 kIPMonitorControlPrefsIDStr,
134 queue, handler);
135 return;
136 }
137
138 #else /* TARGET_OS_IPHONE */
139
140 static void
141 enable_prefs_observer(CFRunLoopRef runloop)
142 {
143 #pragma unused(runloop)
144 return;
145 }
146
147 #endif /* TARGET_OS_IPHONE */
148
149 static void
150 IPMonitorControlPrefsChanged(SCPreferencesRef prefs,
151 SCPreferencesNotification type,
152 void * info)
153 {
154 #pragma unused(prefs)
155 #pragma unused(type)
156 #pragma unused(info)
157 prefs_changed(NULL);
158 return;
159 }
160
161 __private_extern__ SCPreferencesRef
162 IPMonitorControlPrefsInit(CFRunLoopRef runloop,
163 IPMonitorControlPrefsCallBack callback)
164 {
165 S_prefs = SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
166 kIPMonitorControlPrefsID);
167 if (runloop != NULL && callback != NULL) {
168 S_callback = callback;
169 if (!SCPreferencesSetCallback(S_prefs, IPMonitorControlPrefsChanged, NULL)) {
170 SC_log(LOG_NOTICE, "SCPreferencesSetCallBack() failed: %s", SCErrorString(SCError()));
171 goto done;
172 }
173
174 if (!SCPreferencesScheduleWithRunLoop(S_prefs, runloop, kCFRunLoopCommonModes)) {
175 SC_log(LOG_NOTICE, "SCPreferencesScheduleWithRunLoop() failed: %s", SCErrorString(SCError()));
176 (void) SCPreferencesSetCallback(S_prefs, NULL, NULL);
177 }
178
179 enable_prefs_observer(runloop);
180 }
181
182 done :
183 return (S_prefs);
184 }
185
186 static Boolean
187 IPMonitorControlPrefsSave(void)
188 {
189 Boolean saved = FALSE;
190
191 if (S_prefs != NULL) {
192 saved = SCPreferencesCommitChanges(S_prefs);
193 SCPreferencesSynchronize(S_prefs);
194 }
195 return (saved);
196 }
197
198 static CFBooleanRef
199 prefs_get_boolean(CFStringRef key)
200 {
201 CFBooleanRef b = NULL;
202
203 #if TARGET_OS_IPHONE
204 b = SCPreferencesGetValue(IPMonitorControlManagedPrefsGet(), key);
205 b = isA_CFBoolean(b);
206 #endif /* TARGET_OS_IPHONE */
207 if (b == NULL) {
208 b = SCPreferencesGetValue(IPMonitorControlPrefsGet(), key);
209 b = isA_CFBoolean(b);
210 }
211 return (b);
212 }
213
214 static void
215 prefs_set_boolean(CFStringRef key, CFBooleanRef b)
216 {
217 SCPreferencesRef prefs = IPMonitorControlPrefsGet();
218
219 if (prefs != NULL) {
220 if (isA_CFBoolean(b) == NULL) {
221 SCPreferencesRemoveValue(prefs, key);
222 }
223 else {
224 SCPreferencesSetValue(prefs, key, b);
225 }
226 }
227 return;
228 }
229
230 static void
231 IPMonitorControlPrefsRefresh(void)
232 {
233 if (S_prefs != NULL) {
234 SCPreferencesSynchronize(S_prefs);
235 }
236 #if TARGET_OS_IPHONE
237 if (S_managed_prefs != NULL) {
238 SCPreferencesSynchronize(S_managed_prefs);
239 }
240 #endif /* TARGET_OS_IPHONE */
241 return;
242 }
243
244 /**
245 ** Get
246 **/
247 __private_extern__ Boolean
248 IPMonitorControlPrefsIsVerbose(void)
249 {
250 CFBooleanRef b;
251 Boolean verbose = FALSE;
252
253 b = prefs_get_boolean(kVerbose);
254 if (b != NULL) {
255 verbose = CFBooleanGetValue(b);
256 }
257 /* flush the backing store */
258 IPMonitorControlPrefsRefresh();
259 return (verbose);
260 }
261
262 /**
263 ** Set
264 **/
265 __private_extern__ Boolean
266 IPMonitorControlPrefsSetVerbose(Boolean verbose)
267 {
268 if (!verbose) {
269 prefs_set_boolean(kVerbose, NULL);
270 }
271 else {
272 prefs_set_boolean(kVerbose, kCFBooleanTrue);
273 }
274 return (IPMonitorControlPrefsSave());
275 }
276
277 #ifdef TEST_IPMONITORCONTROLPREFS
278 int
279 main(int argc, char * argv[])
280 {
281 Boolean need_usage = FALSE;
282 Boolean success = FALSE;
283
284 if (argc < 2) {
285 need_usage = TRUE;
286 }
287 else if (strcasecmp(argv[1], "on") == 0) {
288 success = IPMonitorControlPrefsSetVerbose(TRUE);
289 }
290 else if (strcasecmp(argv[1], "off") == 0) {
291 success = IPMonitorControlPrefsSetVerbose(FALSE);
292 }
293 else {
294 need_usage = TRUE;
295 }
296 if (need_usage) {
297 fprintf(stderr, "usage: %s ( on | off )\n", argv[0]);
298 exit(1);
299 }
300 if (!success) {
301 fprintf(stderr, "failed to save prefs\n");
302 exit(2);
303 }
304 exit(0);
305 return (0);
306 }
307
308 #endif /* TEST_IPMONITORCONTROLPREFS */