示例#1
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);
}
示例#2
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);
					  });
/* 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;
}