Exemplo n.º 1
0
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();
}
Exemplo n.º 2
0
int HostDnsServiceDarwin::monitorWorker()
{
    m->m_RunLoopRef = CFRunLoopGetCurrent();
    AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR);

    CFRetain(m->m_RunLoopRef);

    CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
                                                (const void **)&kStateNetworkGlobalDNSKey,
                                                1, &kCFTypeArrayCallBacks);
    if (!watchingArrayRef)
    {
        CFRelease(m->m_DnsWatcher);
        return E_OUTOFMEMORY;
    }

    if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
        CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);

    CFRelease(watchingArrayRef);

    monitorThreadInitializationDone();

    while (!m->m_fStop)
    {
        CFRunLoopRun();
    }

    CFRelease(m->m_RunLoopRef);

    /* We're notifying stopper thread. */
    RTSemEventSignal(m->m_evtStop);

    return VINF_SUCCESS;
}
Exemplo n.º 3
0
static int hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser)
{
    NOREF(ThreadSelf);
    NOREF(pvUser);
    g_RunLoopRef = CFRunLoopGetCurrent();
    AssertReturn(g_RunLoopRef, VERR_INTERNAL_ERROR);

    CFRetain(g_RunLoopRef);

    CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
                                                (const void **)&kStateNetworkGlobalDNSKey,
                                                1, &kCFTypeArrayCallBacks);
    if (!watchingArrayRef)
    {
        CFRelease(g_DnsWatcher);
        return E_OUTOFMEMORY;
    }

    if(SCDynamicStoreSetNotificationKeys(g_store, watchingArrayRef, NULL))
        CFRunLoopAddSource(CFRunLoopGetCurrent(), g_DnsWatcher, kCFRunLoopCommonModes);

    CFRelease(watchingArrayRef);

    RTSemEventSignal(g_DnsInitEvent);

    CFRunLoopRun();

    CFRelease(g_RunLoopRef);

    return VINF_SUCCESS;
}
Exemplo n.º 4
0
/*
 * 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;
}
Exemplo n.º 5
0
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
}
Exemplo n.º 6
0
static SCDynamicStoreRef
config_session_start(SCDynamicStoreCallBack func, void * arg, const char * ifname)
{
    SCDynamicStoreContext	context;
    CFStringRef			key;
    SCDynamicStoreRef		store;

    bzero(&context, sizeof(context));
    context.info = arg;
    store = SCDynamicStoreCreate(NULL, CFSTR("/usr/local/bin/eapoltest"), 
				 func, &context);
    if (store == NULL) {
	fprintf(stderr, "SCDynamicStoreCreate() failed, %s",
		SCErrorString(SCError()));
	return (NULL);
    }
    /* EAPClient status notifications */
    if (ifname == NULL) {
	/* watch all interfaces */
	CFArrayRef			patterns;

	key = EAPOLControlAnyInterfaceKeyCreate();
	patterns = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
	CFRelease(key);
	SCDynamicStoreSetNotificationKeys(store, NULL, patterns);
	CFRelease(patterns);
    }
    else {
	/* watch just one interface */
	CFArrayRef			keys = NULL;

	key = EAPOLControlKeyCreate(ifname);
	keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
	CFRelease(key);
	SCDynamicStoreSetNotificationKeys(store, keys, NULL);
	CFRelease(keys);
    }
    return (store);
}
Exemplo n.º 7
0
Arquivo: client.c Projeto: aosm/bootp
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);
}
Exemplo n.º 8
0
static void
watchQuietDisable()
{
	if ((initKey == NULL) || (initRls == NULL)) {
		return;
	}

	(void) SCDynamicStoreSetNotificationKeys(store, NULL, NULL);

	CFRunLoopSourceInvalidate(initRls);
	CFRelease(initRls);
	initRls = NULL;

	CFRelease(initKey);
	initKey = NULL;

	return;
}
Exemplo n.º 9
0
static Boolean RegisterConsoleUserChangeCallback() {
	CFStringRef	consoleUserNameChangeKey = NULL;
	CFArrayRef	notificationKeys = NULL;
	Boolean		success = TRUE;
	
	write_log(LOG_NOTICE, "Creating ConsoleUser key.");
	
	consoleUserNameChangeKey = SCDynamicStoreKeyCreateConsoleUser(NULL);
    if(consoleUserNameChangeKey == NULL) {
		write_log(LOG_ERR, "Couldn't create ConsoleUser key!");
		success = FALSE;
        goto EXIT;
    }
	
	write_log(LOG_NOTICE, "Creating notification key array.");
	
    notificationKeys = CFArrayCreate(NULL, (void*)&consoleUserNameChangeKey, 
									 (CFIndex)1, &kCFTypeArrayCallBacks);
    if(notificationKeys == NULL) {
		write_log(LOG_ERR, "Couldn't create notification key array!"); 
		success = FALSE;
        goto EXIT;
    }
	
	write_log(LOG_NOTICE, "Setting up DynamicStore notification.");
	
	if(SCDynamicStoreSetNotificationKeys(dsSession, notificationKeys, NULL) == 
	   FALSE) {
		write_log(LOG_ERR, "Couldn't set up DynamicStore notification!"); 
		success = FALSE;
        goto EXIT;
	}
	
EXIT:
	if(notificationKeys != NULL) {
		CFRelease(notificationKeys);
		notificationKeys = NULL;
	}
	if(consoleUserNameChangeKey != NULL) {
		CFRelease(consoleUserNameChangeKey);
		consoleUserNameChangeKey = NULL;
	}
	return success;
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
__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,
					  &notify_token,
					  dispatch_get_main_queue(),
					  ^(int token){
						  CFRunLoopPerformBlock(rl,
									kCFRunLoopDefaultMode,
									notify_block);
						  CFRunLoopWakeUp(rl);
					  });
Exemplo n.º 14
0
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);
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
__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;
}
Exemplo n.º 17
0
static void
nc_ondemand(int argc, char **argv)
{
	int			exit_code	= 1;
	CFStringRef		key		= NULL;
	CFDictionaryRef		ondemand_dict	= NULL;
	SCDynamicStoreRef	store;

	store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), nc_ondemand_callback, NULL);
	if (store == NULL) {
		SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError()));
		goto done;
	}

	if (argc == 1) {
#if	!TARGET_IPHONE_SIMULATOR
		if (strcmp("--refresh", argv[0]) == 0) {
			SCNetworkConnectionRef	connection	= NULL;

			connection = SCNetworkConnectionCreate(kCFAllocatorDefault, NULL, NULL);
			if (connection && SCNetworkConnectionRefreshOnDemandState(connection)) {
				exit_code = 0;
			}

			if (exit_code) {
				SCPrint(TRUE, stderr, CFSTR("Unable to refresh OnDemand state: %s\n"), SCErrorString(SCError()));
			}

			my_CFRelease(&connection);
			goto done;
		}
#endif	// !TARGET_IPHONE_SIMULATOR

		ondemand_nodename = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
	} else if (argc != 0) {
		SCPrint(TRUE, stderr, CFSTR("Usage: scutil --nc ondemand [-W] [hostname]\n"
					    "       scutil --nc ondemand -- --refresh\n"));
		goto done;
	}

	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetOnDemand);

	if (ondemand_nodename) {
		checkOnDemandHost(store, ondemand_nodename, FALSE);
		checkOnDemandHost(store, ondemand_nodename, TRUE);
	} else {
		ondemand_dict = SCDynamicStoreCopyValue(store, key);
		if (ondemand_dict) {
			SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), kSCEntNetOnDemand, ondemand_dict);
		} else {
			SCPrint(TRUE, stdout, CFSTR("%@ not configured\n"), kSCEntNetOnDemand);
		}
	}

	if (ondemandwatch) {
		CFMutableArrayRef	keys	= NULL;

		keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
		CFArrayAppendValue(keys, key);
		SCDynamicStoreSetNotificationKeys(store, keys, NULL);

		my_CFRelease(&keys);

		SCDynamicStoreSetDispatchQueue(store, dispatch_get_main_queue());

		CFRunLoopRun();
	}

	exit_code = 0;
done:
	my_CFRelease(&ondemand_dict);
	my_CFRelease(&key);
	my_CFRelease(&store);
	my_CFRelease(&ondemand_nodename);
	exit(exit_code);
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
/*
 * 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;
}
Exemplo n.º 21
0
static Boolean
__SCPreferencesUnscheduleFromRunLoop(SCPreferencesRef	prefs,
				     CFRunLoopRef	runLoop,
				     CFStringRef	runLoopMode)
{
	SCPreferencesPrivateRef	prefsPrivate	= (SCPreferencesPrivateRef)prefs;
	CFIndex			n		= 0;
	Boolean			ok		= FALSE;

	pthread_mutex_lock(&prefsPrivate->lock);

	if ((runLoop != NULL) && !prefsPrivate->scheduled) {			// if we should be scheduled (but are not)
		_SCErrorSet(kSCStatusInvalidArgument);
		goto done;
	}

	if (((runLoop == NULL) && (prefsPrivate->dispatchQueue == NULL)) ||	// if we should be scheduled on a dispatch queue (but are not)
	    ((runLoop != NULL) && (prefsPrivate->dispatchQueue != NULL))) {	// if we should be scheduled on a CFRunLoop (but are scheduled on a dispatch queue)
		_SCErrorSet(kSCStatusInvalidArgument);
		goto done;
	}

	if (runLoop == NULL) {
		SCDynamicStoreSetDispatchQueue(prefsPrivate->session, NULL);
		dispatch_release(prefsPrivate->dispatchQueue);
		prefsPrivate->dispatchQueue = NULL;
	} else {
		if (!_SC_unschedule(prefs, runLoop, runLoopMode, prefsPrivate->rlList, FALSE)) {
			// if not currently scheduled on this runLoop / runLoopMode
			_SCErrorSet(kSCStatusInvalidArgument);
			goto done;
		}

		n = CFArrayGetCount(prefsPrivate->rlList);
		if (n == 0 || !_SC_isScheduled(NULL, runLoop, runLoopMode, prefsPrivate->rlList)) {
			/*
			 * if we are no longer scheduled to receive notifications for
			 * this runLoop / runLoopMode
			 */
			CFRunLoopRemoveSource(runLoop, prefsPrivate->rls, runLoopMode);

			if (n == 0) {
				// if *all* notifications have been unscheduled
				CFRelease(prefsPrivate->rlList);
				prefsPrivate->rlList = NULL;
				CFRunLoopSourceInvalidate(prefsPrivate->rls);
				CFRelease(prefsPrivate->rls);
				prefsPrivate->rls = NULL;
			}
		}
	}

	if (n == 0) {
		CFArrayRef      changedKeys;

		// if *all* notifications have been unscheduled
		prefsPrivate->scheduled = FALSE;

		// no need to track changes
		(void) SCDynamicStoreSetNotificationKeys(prefsPrivate->session, NULL, NULL);

		// clear out any pending notifications
		changedKeys = SCDynamicStoreCopyNotifiedKeys(prefsPrivate->session);
		if (changedKeys != NULL) {
			CFRelease(changedKeys);
		}

		// release our reference to the prefs
		CFRelease(prefs);
	}

	ok = TRUE;

    done :

	pthread_mutex_unlock(&prefsPrivate->lock);
	return ok;
}
Exemplo n.º 22
0
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;
    }
}
Exemplo n.º 23
0
/* 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;
}