NetworkStateNotifier::NetworkStateNotifier() : m_isOnLine(false) , m_networkStateChangeTimer(*this, &NetworkStateNotifier::networkStateChangeTimerFired) { SCDynamicStoreContext context = { 0, this, 0, 0, 0 }; m_store = adoptCF(SCDynamicStoreCreate(0, CFSTR("com.apple.WebCore"), dynamicStoreCallback, &context)); if (!m_store) return; RetainPtr<CFRunLoopSourceRef> configSource = adoptCF(SCDynamicStoreCreateRunLoopSource(0, m_store.get(), 0)); if (!configSource) return; CFRunLoopAddSource(CFRunLoopGetMain(), configSource.get(), kCFRunLoopCommonModes); RetainPtr<CFMutableArrayRef> keys = adoptCF(CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); RetainPtr<CFMutableArrayRef> patterns = adoptCF(CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); RetainPtr<CFStringRef> key; RetainPtr<CFStringRef> pattern; key = adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetIPv4)); CFArrayAppendValue(keys.get(), key.get()); pattern = adoptCF(SCDynamicStoreKeyCreateNetworkInterfaceEntity(0, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4)); CFArrayAppendValue(patterns.get(), pattern.get()); key = adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetDNS)); CFArrayAppendValue(keys.get(), key.get()); SCDynamicStoreSetNotificationKeys(m_store.get(), keys.get(), patterns.get()); updateState(); }
HRESULT HostDnsServiceDarwin::init() { SCDynamicStoreContext ctx; RT_ZERO(ctx); ctx.info = this; m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"), (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback, &ctx); AssertReturn(m->m_store, E_FAIL); m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0); if (!m->m_DnsWatcher) return E_OUTOFMEMORY; int rc = RTSemEventCreate(&m->m_evtStop); AssertRCReturn(rc, E_FAIL); CFRunLoopSourceContext sctx; RT_ZERO(sctx); sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback; m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx); AssertReturn(m->m_Stopper, E_FAIL); HRESULT hrc = HostDnsMonitor::init(); AssertComRCReturn(hrc, hrc); return updateInfo(); }
static Boolean InitDynamicStore() { Boolean success = TRUE; write_log(LOG_NOTICE, "Creating DynamicStore session."); dsSession = SCDynamicStoreCreate(NULL, CFSTR(kProgramName), ConsoleUserChangedCallbackFunction, &dsContext); if(dsSession == NULL) { write_log(LOG_ERR, "Couldn't create DynamicStore session!"); success = FALSE; goto EXIT; } write_log(LOG_NOTICE, "Creating DynamicStore RunLoop source."); dsRunLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, dsSession, (CFIndex)0); if(dsRunLoopSource == NULL) { write_log(LOG_ERR, "Couldn't create DynamicStore RunLoop source!"); success = FALSE; goto EXIT; } CFRunLoopAddSource(CFRunLoopGetCurrent(), dsRunLoopSource, kCFRunLoopDefaultMode); EXIT: return success; }
/* * Wait until a console user logs in (or don't wait if one is already logged in). */ static bool wait_for_console_user(char *devname) { CFStringRef key; CFMutableArrayRef keys; Boolean ok; SCDynamicStoreRef store = NULL; CFRunLoopSourceRef rls; CFStringRef user; uid_t uid; gid_t gid; bool ret = false; store = SCDynamicStoreCreate(NULL, CFSTR("com.apple.nofs"), console_user_changed_cb, NULL); if (store == NULL) { return ret; } /* check if a console user is already logged in */ user = SCDynamicStoreCopyConsoleUser(store, &uid, &gid); if (user != NULL) { CFRelease(user); ret = true; goto out; } /* wait for a notification that a console user logged in */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); key = SCDynamicStoreKeyCreateConsoleUser(NULL); CFArrayAppendValue(keys, key); CFRelease(key); ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL); CFRelease(keys); if (!ok) { syslog(LOG_ERR, "nofs: SCDynamicStoreSetNotificationKeys() failed"); goto out; } rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1); if (rls == NULL) { syslog(LOG_ERR, "nofs: SCDynamicStoreCreateRunLoopSource() failed"); goto out; } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRunLoopRun(); CFRunLoopSourceInvalidate(rls); CFRelease(rls); ret = true; out: if (store) { CFRelease(store); } return ret; }
void KprNetworkInterfaceSetup() { #if TARGET_OS_IPHONE struct sockaddr_in localWifiAddress; SCNetworkReachabilityContext context = {0, NULL, NULL, NULL, NULL}; SCNetworkReachabilityFlags flags; bzero(&localWifiAddress, sizeof(localWifiAddress)); localWifiAddress.sin_len = sizeof(localWifiAddress); localWifiAddress.sin_family = AF_INET; localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0 gNetworkInterfaceReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&localWifiAddress); SCNetworkReachabilitySetCallback(gNetworkInterfaceReachability, KprNetworkInterfaceReachabilityCallback, &context); SCNetworkReachabilityScheduleWithRunLoop(gNetworkInterfaceReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); SCNetworkReachabilityGetFlags(gNetworkInterfaceReachability, &flags); KprNetworkInterfaceReachabilityCallback(gNetworkInterfaceReachability, flags, NULL); #elif TARGET_OS_MAC FskErr err = kFskErrNone; SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; CFStringRef pattern = NULL; CFArrayRef patternList = NULL; pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); if (!pattern) { err = kFskErrOperationFailed; goto bail; } patternList = CFArrayCreate(NULL, (const void **)&pattern, 1, &kCFTypeArrayCallBacks); if (!patternList) { err = kFskErrOperationFailed; goto bail; } gNetworkInterfaceStore = SCDynamicStoreCreate(NULL, CFSTR("KprNetWorkInterface"), KprNetworkInterfaceStoreCallback, &context); if (!gNetworkInterfaceStore) { err = kFskErrOperationFailed; goto bail; } if (!SCDynamicStoreSetNotificationKeys(gNetworkInterfaceStore, NULL, patternList)) { err = kFskErrOperationFailed; goto bail; } gNetworkInterfaceSource = SCDynamicStoreCreateRunLoopSource(NULL, gNetworkInterfaceStore, 0); if (!gNetworkInterfaceSource) { err = kFskErrOperationFailed; goto bail; } CFRunLoopAddSource(CFRunLoopGetCurrent(), gNetworkInterfaceSource, kCFRunLoopCommonModes); KprNetworkInterfaceStoreCallback(gNetworkInterfaceStore, NULL, NULL); bail: if (err != noErr) { if (gNetworkInterfaceSource) { CFRelease(gNetworkInterfaceSource); gNetworkInterfaceSource = NULL; } if (gNetworkInterfaceStore) { CFRelease(gNetworkInterfaceStore); gNetworkInterfaceStore = NULL; } } if (patternList) CFRelease(patternList); if (pattern) CFRelease(pattern); #elif TARGET_OS_WIN32 NETIOAPI_API status = NotifyIpInterfaceChange(AF_INET, &KprNetworkInterfaceCallback, NULL, TRUE, &gNetworkInterfaceHandle); #elif TARGET_OS_KPL #ifdef KPR_CONFIG KplNetInterfaceInitialize(); KplNetInterfaceSetChangedCallback(KprNetworkInterfaceCallback, 0L); KprNetworkInterfaceCallback(0); #endif #endif }
static int S_wait_all(mach_port_t server, int argc, char * argv[]) { CFMutableArrayRef keys; SCDynamicStoreRef session; CFRunLoopSourceRef rls; unsigned long t = WAIT_ALL_DEFAULT_TIMEOUT; CFPropertyListRef value; struct itimerval v; if (argc > 0) { t = strtoul(argv[0], 0, 0); if (t > WAIT_ALL_MAX_TIMEOUT) { t = WAIT_ALL_MAX_TIMEOUT; } } session = SCDynamicStoreCreate(NULL, CFSTR("ipconfig command"), key_appeared, NULL); if (session == NULL) { fprintf(stderr, "SCDynamicStoreCreate failed: %s\n", SCErrorString(SCError())); return (0); } keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(keys, STARTUP_KEY); SCDynamicStoreSetNotificationKeys(session, keys, NULL); CFRelease(keys); rls = SCDynamicStoreCreateRunLoopSource(NULL, session, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); signal(SIGALRM, on_alarm); bzero(&v, sizeof(v)); v.it_value.tv_sec = t; if (setitimer(ITIMER_REAL, &v, NULL) < 0) { perror("setitimer"); return (0); } value = SCDynamicStoreCopyValue(session, STARTUP_KEY); if (value == NULL) { CFRunLoopRun(); return (0); } CFRelease(value); CFRelease(session); return (0); }
int InstallLoginLogoutNotifiers(CFRunLoopSourceRef* RunloopSourceReturned) { SCDynamicStoreContext DynamicStoreContext = { 0, NULL, NULL, NULL, NULL }; SCDynamicStoreRef DynamicStoreCommunicationMechanism = NULL; CFStringRef KeyRepresentingConsoleUserNameChange = NULL; CFMutableArrayRef ArrayOfNotificationKeys; Boolean Result; *RunloopSourceReturned = NULL; DynamicStoreCommunicationMechanism = SCDynamicStoreCreate(NULL, CFSTR("logKext"), LoginLogoutCallBackFunction, &DynamicStoreContext); if (DynamicStoreCommunicationMechanism == NULL) return(-1); //unable to create dynamic store. KeyRepresentingConsoleUserNameChange = SCDynamicStoreKeyCreateConsoleUser(NULL); if (KeyRepresentingConsoleUserNameChange == NULL) { CFRelease(DynamicStoreCommunicationMechanism); return(-2); } ArrayOfNotificationKeys = CFArrayCreateMutable(NULL, (CFIndex)1, &kCFTypeArrayCallBacks); if (ArrayOfNotificationKeys == NULL) { CFRelease(DynamicStoreCommunicationMechanism); CFRelease(KeyRepresentingConsoleUserNameChange); return(-3); } CFArrayAppendValue(ArrayOfNotificationKeys, KeyRepresentingConsoleUserNameChange); Result = SCDynamicStoreSetNotificationKeys(DynamicStoreCommunicationMechanism, ArrayOfNotificationKeys, NULL); CFRelease(ArrayOfNotificationKeys); CFRelease(KeyRepresentingConsoleUserNameChange); if (Result == FALSE) //unable to add keys to dynamic store. { CFRelease(DynamicStoreCommunicationMechanism); return(-4); } *RunloopSourceReturned = SCDynamicStoreCreateRunLoopSource(NULL, DynamicStoreCommunicationMechanism, (CFIndex) 0); return(0); }
static int S_monitor(int argc, char * argv[]) { const char * ifname = NULL; SCDynamicStoreRef store = NULL; CFRunLoopSourceRef rls = NULL; if (argc > 0) { ifname = argv[0]; get_eapol_interface_status(ifname); } store = config_session_start(monitor_eapol_change, NULL, ifname); rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRunLoopRun(); /* not reached */ return (0); }
static CFRunLoopSourceRef InstallComputerNameMonitor(void) { CFRunLoopSourceRef runLoopSource = NULL; SCDynamicStoreContext context = { 0, NULL, NULL, NULL, NULL }; SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("DirectoryService"), ComputerNameChangedCallBack, &context); if (store) { CFStringRef computerNameKey = SCDynamicStoreKeyCreateComputerName(NULL); CFMutableArrayRef keys = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks); CFArrayAppendValue(keys, computerNameKey); if (SCDynamicStoreSetNotificationKeys(store, keys, NULL)) { runLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (runLoopSource) { CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); } } CFRelease(computerNameKey); CFRelease(keys); CFRelease(store); } return runLoopSource; }
static void watchQuietEnable() { CFArrayRef keys; Boolean ok; initKey = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin); initRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), initRls, kCFRunLoopDefaultMode); keys = CFArrayCreate(NULL, (const void **)&initKey, 1, &kCFTypeArrayCallBacks); ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL); CFRelease(keys); if (!ok) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError())); watchQuietDisable(); } return; }
HRESULT HostDnsServiceDarwin::init(const VirtualBox *aParent) { SCDynamicStoreContext ctx; RT_ZERO(ctx); ctx.info = this; g_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"), (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback, &ctx); AssertReturn(g_store, E_FAIL); g_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, g_store, 0); if (!g_DnsWatcher) return E_OUTOFMEMORY; HRESULT hrc = HostDnsService::init(aParent); AssertComRCReturn(hrc, hrc); int rc = RTSemEventCreate(&g_DnsInitEvent); AssertRCReturn(rc, E_FAIL); return update(); }
/* This code adapted from "Living in a Dynamic TCP/IP Environment" technote. */ static Boolean install_ipaddr_source (void) { CFRunLoopSourceRef source = NULL; SCDynamicStoreContext context = {0}; SCDynamicStoreRef ref; ref = SCDynamicStoreCreate (NULL, CFSTR ("AddIPAddressListChangeCallbackSCF"), ipaddr_callback, &context); if (ref != NULL) { const void *keys[4], *patterns[2]; int i; keys[0] = SCDynamicStoreKeyCreateNetworkGlobalEntity (NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4); keys[1] = SCDynamicStoreKeyCreateNetworkGlobalEntity (NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6); keys[2] = SCDynamicStoreKeyCreateComputerName (NULL); keys[3] = SCDynamicStoreKeyCreateHostNames (NULL); patterns[0] = SCDynamicStoreKeyCreateNetworkInterfaceEntity (NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); patterns[1] = SCDynamicStoreKeyCreateNetworkInterfaceEntity (NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6); if (keys[0] != NULL && keys[1] != NULL && keys[2] != NULL && keys[3] != NULL && patterns[0] != NULL && patterns[1] != NULL) { CFArrayRef key_array, pattern_array; key_array = CFArrayCreate (NULL, keys, 4, &kCFTypeArrayCallBacks); pattern_array = CFArrayCreate (NULL, patterns, 2, &kCFTypeArrayCallBacks); if (key_array != NULL || pattern_array != NULL) { SCDynamicStoreSetNotificationKeys (ref, key_array, pattern_array); source = SCDynamicStoreCreateRunLoopSource (NULL, ref, 0); } if (key_array != NULL) CFRelease (key_array); if (pattern_array != NULL) CFRelease (pattern_array); } for (i = 0; i < 4; i++) if (keys[i] != NULL) CFRelease (keys[i]); for (i = 0; i < 2; i++) if (patterns[i] != NULL) CFRelease (patterns[i]); CFRelease (ref); } if (source != NULL) { CFRunLoopAddSource (CFRunLoopGetCurrent (), source, kCFRunLoopDefaultMode); CFRelease (source); } return source != NULL; }
static Boolean __SCPreferencesScheduleWithRunLoop(SCPreferencesRef prefs, CFRunLoopRef runLoop, CFStringRef runLoopMode, dispatch_queue_t queue) { Boolean ok = FALSE; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; pthread_mutex_lock(&prefsPrivate->lock); if ((prefsPrivate->dispatchQueue != NULL) || // if we are already scheduled on a dispatch queue ((queue != NULL) && prefsPrivate->scheduled)) { // if we are already scheduled on a CFRunLoop _SCErrorSet(kSCStatusInvalidArgument); goto done; } if (!prefsPrivate->scheduled) { CFMutableArrayRef keys; if (prefsPrivate->session == NULL) { ok = __SCPreferencesAddSession(prefs); if (!ok) { goto done; } } CFRetain(prefs); // hold a reference to the prefs keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(keys, prefsPrivate->sessionKeyCommit); CFArrayAppendValue(keys, prefsPrivate->sessionKeyApply); (void) SCDynamicStoreSetNotificationKeys(prefsPrivate->session, keys, NULL); CFRelease(keys); if (runLoop != NULL) { prefsPrivate->rls = SCDynamicStoreCreateRunLoopSource(NULL, prefsPrivate->session, 0); prefsPrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } prefsPrivate->scheduled = TRUE; } if (queue != NULL) { ok = SCDynamicStoreSetDispatchQueue(prefsPrivate->session, queue); if (!ok) { prefsPrivate->scheduled = FALSE; (void) SCDynamicStoreSetNotificationKeys(prefsPrivate->session, NULL, NULL); CFRelease(prefs); goto done; } prefsPrivate->dispatchQueue = queue; dispatch_retain(prefsPrivate->dispatchQueue); } else { if (!_SC_isScheduled(NULL, runLoop, runLoopMode, prefsPrivate->rlList)) { /* * if we do not already have notifications scheduled with * this runLoop / runLoopMode */ CFRunLoopAddSource(runLoop, prefsPrivate->rls, runLoopMode); } _SC_schedule(prefs, runLoop, runLoopMode, prefsPrivate->rlList); } ok = TRUE; done : pthread_mutex_unlock(&prefsPrivate->lock); return ok; }
static OSStatus CreateIPAddressListChangeCallbackSCF(SCDynamicStoreCallBack callback, void *contextPtr, SCDynamicStoreRef *storeRef, CFRunLoopSourceRef *sourceRef) // Create a SCF dynamic store reference and a // corresponding CFRunLoop source. If you add the // run loop source to your run loop then the supplied // callback function will be called when local IP // address list changes. { OSStatus err = 0; SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; SCDynamicStoreRef ref; CFStringRef pattern; CFArrayRef patternList; CFRunLoopSourceRef rls; assert(callback != NULL); assert( storeRef != NULL); assert(*storeRef == NULL); assert( sourceRef != NULL); assert(*sourceRef == NULL); ref = NULL; pattern = NULL; patternList = NULL; rls = NULL; // Create a connection to the dynamic store, then create // a search pattern that finds all IPv4 entities. // The pattern is "State:/Network/Service/[^/]+/IPv4". context.info = contextPtr; ref = SCDynamicStoreCreate( NULL, CFSTR("AddIPAddressListChangeCallbackSCF"), callback, &context); //err = MoreSCError(ref); if (err == noErr) { pattern = SCDynamicStoreKeyCreateNetworkServiceEntity( NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); //err = MoreSCError(pattern); } // Create a pattern list containing just one pattern, // then tell SCF that we want to watch changes in keys // that match that pattern list, then create our run loop // source. if (err == noErr) { patternList = CFArrayCreate(NULL, (const void **) &pattern, 1, &kCFTypeArrayCallBacks); //err = CFQError(patternList); } if (err == noErr) { //err = MoreSCErrorBoolean( SCDynamicStoreSetNotificationKeys( ref, NULL, patternList); // ); } if (err == noErr) { rls = SCDynamicStoreCreateRunLoopSource(NULL, ref, 0); //err = MoreSCError(rls); } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); // Clean up. //CFQRelease(pattern); //CFQRelease(patternList); if (err != noErr) { //CFQRelease(ref); ref = NULL; } *storeRef = ref; *sourceRef = rls; assert( (err == noErr) == (*storeRef != NULL) ); assert( (err == noErr) == (*sourceRef != NULL) ); return err; }
/* * startKicker() * * The first argument is a dictionary representing the keys * which need to be monitored for a given "target" and what * action should be taken if a change in one of those keys * is detected. */ static void startKicker(const void *value, void *context) { CFMutableStringRef name; CFArrayRef keys; CFArrayRef patterns; kickeeRef target = CFAllocatorAllocate(NULL, sizeof(kickee), 0); SCDynamicStoreContext targetContext = { 0, (void *)target, NULL, NULL, NULL }; target->active = FALSE; target->needsKick = FALSE; target->dict = CFRetain((CFDictionaryRef)value); target->store = NULL; target->rl = NULL; target->rls = NULL; target->changedKeys = NULL; name = CFStringCreateMutableCopy(NULL, 0, CFDictionaryGetValue(target->dict, CFSTR("name"))); SCLog(TRUE, LOG_DEBUG, CFSTR("Starting kicker for %@"), name); CFStringAppend(name, CFSTR(" \"Kicker\"")); target->store = SCDynamicStoreCreate(NULL, name, kicker, &targetContext); CFRelease(name); if (!target->store) { SCLog(TRUE, LOG_NOTICE, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } keys = isA_CFArray(CFDictionaryGetValue(target->dict, CFSTR("keys"))); patterns = isA_CFArray(CFDictionaryGetValue(target->dict, CFSTR("regexKeys"))); if (!SCDynamicStoreSetNotificationKeys(target->store, keys, patterns)) { SCLog(TRUE, LOG_NOTICE, CFSTR("SCDynamicStoreSetNotifications() failed: %s"), SCErrorString(SCError())); goto error; } target->rl = CFRunLoopGetCurrent(); target->rls = SCDynamicStoreCreateRunLoopSource(NULL, target->store, 0); if (!target->rls) { SCLog(TRUE, LOG_NOTICE, CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"), SCErrorString(SCError())); goto error; } CFRunLoopAddSource(target->rl, target->rls, kCFRunLoopDefaultMode); return; error : CFRelease(target->dict); if (target->store) CFRelease(target->store); CFAllocatorDeallocate(NULL, target); return; }
__private_extern__ Boolean __SCDynamicStoreReconnectNotifications(SCDynamicStoreRef store) { dispatch_queue_t dispatchQueue = NULL; __SCDynamicStoreNotificationStatus notifyStatus; Boolean ok = TRUE; CFArrayRef rlList = NULL; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; // save old SCDynamicStore [notification] state notifyStatus = storePrivate->notifyStatus; // before tearing down our [old] notifications, make sure we've // retained any information that will be lost when we cancel the // current no-longer-valid handler switch (notifyStatus) { case Using_NotifierInformViaRunLoop : if (storePrivate->rlList != NULL) { rlList = CFArrayCreateCopy(NULL, storePrivate->rlList); } case Using_NotifierInformViaDispatch : dispatchQueue = storePrivate->dispatchQueue; if (dispatchQueue != NULL) dispatch_retain(dispatchQueue); break; default : break; } // cancel [old] notifications if (!SCDynamicStoreNotifyCancel(store)) { // if we could not cancel / reconnect SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreReconnectNotifications: SCDynamicStoreNotifyCancel() failed: %s"), SCErrorString(SCError())); } // set notification keys & patterns if ((storePrivate->keys != NULL) || (storePrivate->patterns)) { ok = SCDynamicStoreSetNotificationKeys(store, storePrivate->keys, storePrivate->patterns); if (!ok) { SCLog((SCError() != BOOTSTRAP_UNKNOWN_SERVICE), LOG_ERR, CFSTR("__SCDynamicStoreReconnectNotifications: SCDynamicStoreSetNotificationKeys() failed")); goto done; } } switch (notifyStatus) { case Using_NotifierInformViaRunLoop : { CFIndex i; CFIndex n; CFRunLoopSourceRef rls; rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (rls == NULL) { SCLog((SCError() != BOOTSTRAP_UNKNOWN_SERVICE), LOG_ERR, CFSTR("__SCDynamicStoreReconnectNotifications: SCDynamicStoreCreateRunLoopSource() failed")); ok = FALSE; break; } n = (rlList != NULL) ? CFArrayGetCount(rlList) : 0; for (i = 0; i < n; i += 3) { CFRunLoopRef rl = (CFRunLoopRef)CFArrayGetValueAtIndex(rlList, i+1); CFStringRef rlMode = (CFStringRef) CFArrayGetValueAtIndex(rlList, i+2); CFRunLoopAddSource(rl, rls, rlMode); } CFRelease(rls); break; } case Using_NotifierInformViaDispatch : ok = SCDynamicStoreSetDispatchQueue(store, dispatchQueue); if (!ok) { SCLog((SCError() != BOOTSTRAP_UNKNOWN_SERVICE), LOG_ERR, CFSTR("__SCDynamicStoreReconnectNotifications: SCDynamicStoreSetDispatchQueue() failed")); goto done; } break; default : _SCErrorSet(kSCStatusFailed); ok = FALSE; break; } done : // cleanup switch (notifyStatus) { case Using_NotifierInformViaRunLoop : if (rlList != NULL) CFRelease(rlList); break; case Using_NotifierInformViaDispatch : if (dispatchQueue != NULL) dispatch_release(dispatchQueue); break; default : break; } if (!ok) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore server %s, notification (%s) not restored"), (SCError() == BOOTSTRAP_UNKNOWN_SERVICE) ? "shutdown" : "failed", notifyType[notifyStatus]); } // inform the client pushDisconnect(store); return ok; }
void load(CFBundleRef bundle, Boolean bundleVerbose) { CFStringRef key; CFMutableArrayRef keys = NULL; CFStringRef pattern; CFMutableArrayRef patterns = NULL; CFRunLoopSourceRef rls; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* initialize a few globals */ curGlobals = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); curDefaults = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curStartup = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* open a "configd" store to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("AppleTalk Configuraton plug-in"), atConfigChangedCallback, NULL); if (!store) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* establish notificaiton keys and patterns */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); /* ...watch for (global) AppleTalk configuration changes */ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, kSCEntNetAppleTalk); CFArrayAppendValue(keys, key); CFRelease(key); /* ...watch for (per-service) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for network interface link status changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetLink); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for (per-interface) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for computer name changes */ key = SCDynamicStoreKeyCreateComputerName(NULL); CFArrayAppendValue(keys, key); CFRelease(key); /* register the keys/patterns */ if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError())); goto error; } rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (!rls) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"), SCErrorString(SCError())); goto error; } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRelease(keys); CFRelease(patterns); return; error : if (curGlobals) CFRelease(curGlobals); if (curConfigFile) CFRelease(curConfigFile); if (curDefaults) CFRelease(curDefaults); if (curStartup) CFRelease(curStartup); if (store) CFRelease(store); if (keys) CFRelease(keys); if (patterns) CFRelease(patterns); return; }
static void SetInterfaceChangedObserver_MacDesktop(OsContext* aContext, InterfaceListChanged aCallback, void* aArg) { SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; CFStringRef pattern = NULL; CFArrayRef patternList = NULL; CFRunLoopRef runLoop = NULL; if (NULL != aContext->iInterfaceChangedObserver) { return; } aContext->iInterfaceChangedObserver = (InterfaceChangedObserver*)malloc(sizeof(*(aContext->iInterfaceChangedObserver))); if (NULL == aContext->iInterfaceChangedObserver) { goto Error; } aContext->iInterfaceChangedObserver->iCallback = aCallback; aContext->iInterfaceChangedObserver->iArg = aArg; aContext->iInterfaceChangedObserver->iStore = NULL; aContext->iInterfaceChangedObserver->iRunLoopSource = NULL; context.info = aContext->iInterfaceChangedObserver; aContext->iInterfaceChangedObserver->iStore = SCDynamicStoreCreate(NULL, CFSTR("AddIPAddressListChangeCallbackSCF"), &InterfaceChangedDynamicStoreCallback, &context); if (NULL == aContext->iInterfaceChangedObserver->iStore) { goto Error; } pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); if (NULL == pattern) { goto Error; } patternList = CFArrayCreate(NULL, (const void **)&pattern, 1, &kCFTypeArrayCallBacks); if (NULL == patternList) { goto Error; } if (false == SCDynamicStoreSetNotificationKeys(aContext->iInterfaceChangedObserver->iStore, NULL, patternList)) { goto Error; } aContext->iInterfaceChangedObserver->iRunLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, aContext->iInterfaceChangedObserver->iStore, 0); if (NULL == aContext->iInterfaceChangedObserver->iRunLoopSource) { goto Error; } runLoop = CFRunLoopGetMain(); if (NULL == runLoop) { goto Error; } CFRunLoopAddSource(runLoop, aContext->iInterfaceChangedObserver->iRunLoopSource, kCFRunLoopCommonModes); CFRelease(pattern); CFRelease(patternList); return; Error: if (NULL != pattern) { CFRelease(pattern); } if (NULL != patternList) { CFRelease(patternList); } if (NULL != aContext->iInterfaceChangedObserver) { if (aContext->iInterfaceChangedObserver->iStore != NULL) { CFRelease(aContext->iInterfaceChangedObserver->iStore); } if (aContext->iInterfaceChangedObserver->iRunLoopSource != NULL) { CFRelease(aContext->iInterfaceChangedObserver->iRunLoopSource); } free(aContext->iInterfaceChangedObserver); aContext->iInterfaceChangedObserver = NULL; } }
__private_extern__ void load_smb_configuration(Boolean verbose) { CFStringRef key; CFMutableArrayRef keys = NULL; dispatch_block_t notify_block; Boolean ok; CFMutableArrayRef patterns = NULL; uint32_t status; /* initialize a few globals */ store = SCDynamicStoreCreate(NULL, CFSTR("smb-configuration"), configuration_changed, NULL); if (store == NULL) { my_log(LOG_ERR, "SCDynamicStoreCreate() failed: %s", SCErrorString(SCError())); goto error; } /* establish notification keys and patterns */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); /* ...watch for SMB configuration changes */ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetSMB); CFArrayAppendValue(keys, key); CFRelease(key); /* ...watch for ComputerName changes */ key = SCDynamicStoreKeyCreateComputerName(NULL); CFArrayAppendValue(keys, key); CFRelease(key); /* ...watch for local (multicast DNS) hostname changes */ key = SCDynamicStoreKeyCreateHostNames(NULL); CFArrayAppendValue(keys, key); CFRelease(key); /* register the keys/patterns */ ok = SCDynamicStoreSetNotificationKeys(store, keys, patterns); CFRelease(keys); CFRelease(patterns); if (!ok) { my_log(LOG_ERR, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError())); goto error; } rl = CFRunLoopGetCurrent(); rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (rls == NULL) { my_log(LOG_ERR, "SCDynamicStoreCreateRunLoopSource() failed: %s", SCErrorString(SCError())); goto error; } CFRunLoopAddSource(rl, rls, kCFRunLoopDefaultMode); /* ...watch for primary service/interface and DNS configuration changes */ notify_block = ^{ CFArrayRef changes; CFStringRef key; key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetDNS); changes = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks); (*configuration_changed)(store, changes, NULL); CFRelease(changes); CFRelease(key); return; }; status = notify_register_dispatch(_SC_NOTIFY_NETWORK_CHANGE, ¬ify_token, dispatch_get_main_queue(), ^(int token){ CFRunLoopPerformBlock(rl, kCFRunLoopDefaultMode, notify_block); CFRunLoopWakeUp(rl); });
static void * /* O - Return status/value */ sysEventThreadEntry(void) { io_object_t powerNotifierObj; /* Power notifier object */ IONotificationPortRef powerNotifierPort; /* Power notifier port */ SCDynamicStoreRef store = NULL;/* System Config dynamic store */ CFRunLoopSourceRef powerRLS = NULL,/* Power runloop source */ storeRLS = NULL;/* System Config runloop source */ CFStringRef key[6], /* System Config keys */ pattern[2]; /* System Config patterns */ CFArrayRef keys = NULL, /* System Config key array*/ patterns = NULL;/* System Config pattern array */ SCDynamicStoreContext storeContext; /* Dynamic store context */ CFRunLoopTimerContext timerContext; /* Timer context */ cupsd_thread_data_t threadData; /* Thread context data for the * * runloop notifiers */ /* * Register for power state change notifications */ bzero(&threadData, sizeof(threadData)); threadData.sysevent.powerKernelPort = IORegisterForSystemPower(&threadData, &powerNotifierPort, sysEventPowerNotifier, &powerNotifierObj); if (threadData.sysevent.powerKernelPort) { powerRLS = IONotificationPortGetRunLoopSource(powerNotifierPort); CFRunLoopAddSource(CFRunLoopGetCurrent(), powerRLS, kCFRunLoopDefaultMode); } else DEBUG_puts("sysEventThreadEntry: error registering for system power " "notifications"); /* * Register for system configuration change notifications */ bzero(&storeContext, sizeof(storeContext)); storeContext.info = &threadData; store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), sysEventConfigurationNotifier, &storeContext); if (!ComputerNameKey) ComputerNameKey = SCDynamicStoreKeyCreateComputerName(kCFAllocatorDefault); if (!BTMMKey) BTMMKey = SCDynamicStoreKeyCreate(kCFAllocatorDefault, CFSTR("Setup:/Network/BackToMyMac")); if (!NetworkGlobalKeyIPv4) NetworkGlobalKeyIPv4 = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv4); if (!NetworkGlobalKeyIPv6) NetworkGlobalKeyIPv6 = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv6); if (!NetworkGlobalKeyDNS) NetworkGlobalKeyDNS = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetDNS); if (!HostNamesKey) HostNamesKey = SCDynamicStoreKeyCreateHostNames(kCFAllocatorDefault); if (!NetworkInterfaceKeyIPv4) NetworkInterfaceKeyIPv4 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); if (!NetworkInterfaceKeyIPv6) NetworkInterfaceKeyIPv6 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6); if (store && ComputerNameKey && HostNamesKey && NetworkGlobalKeyIPv4 && NetworkGlobalKeyIPv6 && NetworkGlobalKeyDNS && NetworkInterfaceKeyIPv4 && NetworkInterfaceKeyIPv6) { key[0] = ComputerNameKey; key[1] = BTMMKey; key[2] = NetworkGlobalKeyIPv4; key[3] = NetworkGlobalKeyIPv6; key[4] = NetworkGlobalKeyDNS; key[5] = HostNamesKey; pattern[0] = NetworkInterfaceKeyIPv4; pattern[1] = NetworkInterfaceKeyIPv6; keys = CFArrayCreate(kCFAllocatorDefault, (const void **)key, sizeof(key) / sizeof(key[0]), &kCFTypeArrayCallBacks); patterns = CFArrayCreate(kCFAllocatorDefault, (const void **)pattern, sizeof(pattern) / sizeof(pattern[0]), &kCFTypeArrayCallBacks); if (keys && patterns && SCDynamicStoreSetNotificationKeys(store, keys, patterns)) { if ((storeRLS = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, store, 0)) != NULL) { CFRunLoopAddSource(CFRunLoopGetCurrent(), storeRLS, kCFRunLoopDefaultMode); } else DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreCreateRunLoopSource " "failed: %s\n", SCErrorString(SCError()))); } else DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreSetNotificationKeys " "failed: %s\n", SCErrorString(SCError()))); } else DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreCreate failed: %s\n", SCErrorString(SCError()))); if (keys) CFRelease(keys); if (patterns) CFRelease(patterns); /* * Set up a timer to delay the wake change notifications. * * The initial time is set a decade or so into the future, we'll adjust * this later. */ bzero(&timerContext, sizeof(timerContext)); timerContext.info = &threadData; threadData.timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + (86400L * 365L * 10L), 86400L * 365L * 10L, 0, 0, sysEventTimerNotifier, &timerContext); CFRunLoopAddTimer(CFRunLoopGetCurrent(), threadData.timerRef, kCFRunLoopDefaultMode); /* * Store our runloop in a global so the main thread can use it to stop us. */ pthread_mutex_lock(&SysEventThreadMutex); SysEventRunloop = CFRunLoopGetCurrent(); pthread_cond_signal(&SysEventThreadCond); pthread_mutex_unlock(&SysEventThreadMutex); /* * Disappear into the runloop until it's stopped by the main thread. */ CFRunLoopRun(); /* * Clean up before exiting. */ if (threadData.timerRef) { CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), threadData.timerRef, kCFRunLoopDefaultMode); CFRelease(threadData.timerRef); } if (threadData.sysevent.powerKernelPort) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), powerRLS, kCFRunLoopDefaultMode); IODeregisterForSystemPower(&powerNotifierObj); IOServiceClose(threadData.sysevent.powerKernelPort); IONotificationPortDestroy(powerNotifierPort); } if (storeRLS) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), storeRLS, kCFRunLoopDefaultMode); CFRunLoopSourceInvalidate(storeRLS); CFRelease(storeRLS); } if (store) CFRelease(store); pthread_exit(NULL); }