IPMonitorControlPrefs.c [plain text]
#include <TargetConditionals.h>
#include <SystemConfiguration/SCPreferences.h>
#include <SystemConfiguration/SCPrivate.h>
#include <SystemConfiguration/scprefs_observer.h>
#include "IPMonitorControlPrefs.h"
os_log_t __log_IPMonitor();
#define kIPMonitorControlPrefsIDStr "com.apple.IPMonitor.control.plist"
#define kIPMonitorControlPrefsID CFSTR(kIPMonitorControlPrefsIDStr)
#define kVerbose CFSTR("Verbose")
static SCPreferencesRef S_prefs;
static IPMonitorControlPrefsCallBack S_callback;
static SCPreferencesRef
IPMonitorControlPrefsGet(void)
{
if (S_prefs == NULL) {
IPMonitorControlPrefsInit(NULL, NULL);
}
return (S_prefs);
}
static void
prefs_changed(__unused void * arg)
{
os_activity_t activity;
activity = os_activity_create("processing IPMonitor [rank] preference change",
OS_ACTIVITY_CURRENT,
OS_ACTIVITY_FLAG_DEFAULT);
os_activity_scope(activity);
if (S_callback != NULL) {
(*S_callback)(S_prefs);
}
os_release(activity);
return;
}
#if TARGET_OS_IPHONE
#define kManagedPrefsDirStr "/Library/Managed Preferences/mobile/"
#define kIPMonitorControlManagedPrefsID CFSTR(kManagedPrefsDirStr \
kIPMonitorControlPrefsIDStr)
static SCPreferencesRef S_managed_prefs;
static SCPreferencesRef
IPMonitorControlManagedPrefsGet(void)
{
if (S_managed_prefs == NULL) {
S_managed_prefs
= SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
kIPMonitorControlManagedPrefsID);
}
return (S_managed_prefs);
}
static void
enable_prefs_observer(CFRunLoopRef runloop)
{
CFRunLoopSourceContext context;
dispatch_block_t handler;
dispatch_queue_t queue;
CFRunLoopSourceRef source;
bzero(&context, sizeof(context));
context.perform = prefs_changed;
source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes);
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
handler = ^{
if (source != NULL) {
CFRunLoopSourceSignal(source);
if (runloop != NULL) {
CFRunLoopWakeUp(runloop);
}
};
};
_scprefs_observer_watch(scprefs_observer_type_global,
kIPMonitorControlPrefsIDStr,
queue, handler);
return;
}
#else
static void
enable_prefs_observer(CFRunLoopRef runloop)
{
return;
}
#endif
static void
IPMonitorControlPrefsChanged(SCPreferencesRef prefs,
SCPreferencesNotification type,
void * info)
{
prefs_changed(NULL);
return;
}
__private_extern__ SCPreferencesRef
IPMonitorControlPrefsInit(CFRunLoopRef runloop,
IPMonitorControlPrefsCallBack callback)
{
S_prefs = SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
kIPMonitorControlPrefsID);
if (runloop != NULL && callback != NULL) {
S_callback = callback;
if (!SCPreferencesSetCallback(S_prefs, IPMonitorControlPrefsChanged, NULL)) {
SC_log(LOG_NOTICE, "SCPreferencesSetCallBack() failed: %s", SCErrorString(SCError()));
goto done;
}
if (!SCPreferencesScheduleWithRunLoop(S_prefs, runloop, kCFRunLoopCommonModes)) {
SC_log(LOG_NOTICE, "SCPreferencesScheduleWithRunLoop() failed: %s", SCErrorString(SCError()));
(void) SCPreferencesSetCallback(S_prefs, NULL, NULL);
}
enable_prefs_observer(runloop);
}
done :
return (S_prefs);
}
static Boolean
IPMonitorControlPrefsSave(void)
{
Boolean saved = FALSE;
if (S_prefs != NULL) {
saved = SCPreferencesCommitChanges(S_prefs);
SCPreferencesSynchronize(S_prefs);
}
return (saved);
}
static CFBooleanRef
prefs_get_boolean(CFStringRef key)
{
CFBooleanRef b = NULL;
#if TARGET_OS_IPHONE
b = SCPreferencesGetValue(IPMonitorControlManagedPrefsGet(), key);
b = isA_CFBoolean(b);
#endif
if (b == NULL) {
b = SCPreferencesGetValue(IPMonitorControlPrefsGet(), key);
b = isA_CFBoolean(b);
}
return (b);
}
static void
prefs_set_boolean(CFStringRef key, CFBooleanRef b)
{
SCPreferencesRef prefs = IPMonitorControlPrefsGet();
if (prefs != NULL) {
if (isA_CFBoolean(b) == NULL) {
SCPreferencesRemoveValue(prefs, key);
}
else {
SCPreferencesSetValue(prefs, key, b);
}
}
return;
}
static void
IPMonitorControlPrefsRefresh(void)
{
if (S_prefs != NULL) {
SCPreferencesSynchronize(S_prefs);
}
#if TARGET_OS_IPHONE
if (S_managed_prefs != NULL) {
SCPreferencesSynchronize(S_managed_prefs);
}
#endif
return;
}
__private_extern__ Boolean
IPMonitorControlPrefsIsVerbose(void)
{
CFBooleanRef b;
Boolean verbose = FALSE;
b = prefs_get_boolean(kVerbose);
if (b != NULL) {
verbose = CFBooleanGetValue(b);
}
IPMonitorControlPrefsRefresh();
return (verbose);
}
__private_extern__ Boolean
IPMonitorControlPrefsSetVerbose(Boolean verbose)
{
if (!verbose) {
prefs_set_boolean(kVerbose, NULL);
}
else {
prefs_set_boolean(kVerbose, kCFBooleanTrue);
}
return (IPMonitorControlPrefsSave());
}
#ifdef TEST_IPMONITORCONTROLPREFS
int
main(int argc, char * argv[])
{
Boolean need_usage = FALSE;
Boolean success = FALSE;
if (argc < 2) {
need_usage = TRUE;
}
else if (strcasecmp(argv[1], "on") == 0) {
success = IPMonitorControlPrefsSetVerbose(TRUE);
}
else if (strcasecmp(argv[1], "off") == 0) {
success = IPMonitorControlPrefsSetVerbose(FALSE);
}
else {
need_usage = TRUE;
}
if (need_usage) {
fprintf(stderr, "usage: %s ( on | off )\n", argv[0]);
exit(1);
}
if (!success) {
fprintf(stderr, "failed to save prefs\n");
exit(2);
}
exit(0);
return (0);
}
#endif