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