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