/***************************************************************************** * 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); }