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