示例#1
0
/*****************************************************************************
 * AddEventToPlugin
 * - 
 * This method is invoked when launchd wishes the plugin to setup a launch 
 * event matching the parameters in the dictionary.
 *****************************************************************************/
void AddEventToPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef launchdToken, CFDictionaryRef eventParameters)
{
	CFStringRef		domain = CFDictionaryGetValue(eventParameters, sServiceDomainKey);
	CFStringRef		type = CFDictionaryGetValue(eventParameters, sServiceTypeKey);
	CFStringRef		name = CFDictionaryGetValue(eventParameters, sServiceNameKey);
	CFBooleanRef	cfOnAdd = CFDictionaryGetValue(eventParameters, sOnServiceAddKey);
	CFBooleanRef	cfOnRemove = CFDictionaryGetValue(eventParameters, sOnServiceRemoveKey);
	CFBooleanRef    cfWhileSericeExists = CFDictionaryGetValue(eventParameters, sWhileServiceExistsKey);
	
	Boolean			onAdd = false;
	Boolean			onRemove = false;
	Boolean			whileExists = false;
	
	if (cfOnAdd && CFGetTypeID(cfOnRemove) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnAdd))
		onAdd = true;
	
	if (cfOnRemove && CFGetTypeID(cfOnRemove) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnRemove))
		onRemove = true;
	
	if (cfWhileSericeExists && CFGetTypeID(cfWhileSericeExists) == CFBooleanGetTypeID() && CFBooleanGetValue(cfWhileSericeExists))
		whileExists = true;
	
	// A type is required. If none is specified, BAIL
	if (!type || CFGetTypeID(type) != CFStringGetTypeID()) 
	{
		fprintf(stderr, "%s, a LaunchEvent is missing a service type.\n", sPluginIdentifier);
		return;
	}
	
	// If we aren't suppose to launch on services appearing or disappearing, this service does nothing. Ignore.
	if ((!onAdd && !onRemove && !whileExists) || (onAdd && onRemove && whileExists))
	{
		fprintf(stderr, "%s, a LaunchEvent is missing both onAdd/onRemove/existance or has both.\n", sPluginIdentifier);
		return;
	}

	// If no domain is specified, assume local.
	if (!domain)
	{
		domain = CFSTR("local"); 
	}
	else if (CFGetTypeID(domain) != CFStringGetTypeID() ) // If the domain is not a string, fai;
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}

	
	// If we have a name filter, but it's not a string. This event it broken, bail.
	if (name && CFGetTypeID(name) != CFStringGetTypeID())
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}
	
	// Get us a browser
	NetBrowserInfo* browser = CreateBrowserForTypeAndDomain(plugin, type, domain);
	
	if (!browser)
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}
	
	// Create Event Dictionary
	CFMutableDictionaryRef eventDictionary = CFDictionaryCreateMutable(NULL, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	
	
	CFDictionarySetValue(eventDictionary, sLaunchdTokenKey, launchdToken);
	
	if (name)
		CFDictionarySetValue(eventDictionary, sServiceNameKey, name);
	
	// Add to the correct dictionary.
	if (onAdd)
		AddEventDictionary(eventDictionary, plugin->_onAddEvents, browser);
	
	if (onRemove)
		AddEventDictionary(eventDictionary, plugin->_onRemoveEvents, browser);
	
	if (whileExists)
		AddEventDictionary(eventDictionary, plugin->_whileServiceExist, browser);
	
	// Add Token Mapping
	CFDictionarySetValue(plugin->_tokenToBrowserMap, launchdToken, browser);
	
	// Release Memory
	CFRelease(eventDictionary);
	NetBrowserInfoRelease(NULL, browser);
	
}
/*****************************************************************************
* AddEventToPlugin
* -
* This method is invoked when launchd wishes the plugin to setup a launch
* event matching the parameters in the dictionary.
*****************************************************************************/
void AddEventToPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef launchdToken, CFDictionaryRef eventParameters)
{
    CFStringRef domain = CFDictionaryGetValue(eventParameters, sServiceDomainKey);
    CFStringRef type = CFDictionaryGetValue(eventParameters, sServiceTypeKey);
    CFStringRef name = CFDictionaryGetValue(eventParameters, sServiceNameKey);
    CFBooleanRef cfOnAdd = CFDictionaryGetValue(eventParameters, sOnServiceAddKey);
    CFBooleanRef cfOnRemove = CFDictionaryGetValue(eventParameters, sOnServiceRemoveKey);

    Boolean onAdd = false;
    Boolean onRemove = false;

    if (cfOnAdd && CFGetTypeID(cfOnAdd) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnAdd))
        onAdd = true;

    if (cfOnRemove && CFGetTypeID(cfOnRemove) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnRemove))
        onRemove = true;

    // A type is required. If none is specified, BAIL
    if (!type || CFGetTypeID(type) != CFStringGetTypeID())
    {
        fprintf(stderr, "%s:%s: a LaunchEvent is missing a service type.\n", sPluginIdentifier, __FUNCTION__);
        return;
    }

    // If we aren't suppose to launch on services appearing or disappearing, this service does nothing. Ignore.
    if (!onAdd && !onRemove)
    {
        fprintf(stderr, "%s:%s a LaunchEvent is missing both onAdd and onRemove events\n", sPluginIdentifier, __FUNCTION__);
        return;
    }

    // If no domain is specified, assume local.
    if (!domain)
    {
        domain = CFSTR("local");
    }
    else if (CFGetTypeID(domain) != CFStringGetTypeID() ) // If the domain is not a string, fail
    {
        fprintf(stderr, "%s:%s a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier, __FUNCTION__);
        return;
    }

    // If we have a name filter, but it's not a string. This event is broken, bail.
    if (name && CFGetTypeID(name) != CFStringGetTypeID())
    {
        fprintf(stderr, "%s:%s a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier, __FUNCTION__);
        return;
    }

    // Get us a browser
    NetBrowserInfo* browser = CreateBrowser(plugin, type, domain);

    if (!browser)
    {
        fprintf(stderr, "%s:%s cannot create browser\n", sPluginIdentifier, __FUNCTION__);
        return;
    }

    // Create Event Dictionary
    CFMutableDictionaryRef eventDictionary = CFDictionaryCreateMutable(NULL, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    // We store both the Token and the Dictionary. UserEventAgentSetLaunchEventState needs
    // the token and UserEventAgentSetFireEvent needs both the token and the dictionary
    CFDictionarySetValue(eventDictionary, sLaunchdTokenKey, launchdToken);
    CFDictionarySetValue(eventDictionary, sLaunchdDictKey, eventParameters);

    if (name)
        CFDictionarySetValue(eventDictionary, sServiceNameKey, name);

    // Add to the correct dictionary.
    if (onAdd)
    {
        asl_log(NULL, NULL, ASL_LEVEL_INFO, "%s:%s: Adding browser to AddEvents", sPluginIdentifier, __FUNCTION__);
        AddEventDictionary(eventDictionary, plugin->_onAddEvents, browser);
    }

    if (onRemove)
    {
        asl_log(NULL, NULL, ASL_LEVEL_INFO, "%s:%s: Adding browser to RemoveEvents", sPluginIdentifier, __FUNCTION__);
        AddEventDictionary(eventDictionary, plugin->_onRemoveEvents, browser);
    }

    // Add Token Mapping
    CFDictionarySetValue(plugin->_tokenToBrowserMap, launchdToken, browser);

    // Release Memory
    CFRelease(eventDictionary);
}