示例#1
0
void DAFileSystemListRefresh( void )
{
    struct stat status1;
    struct stat status2;

    /*
     * Determine whether the file system list is up-to-date.
     */

    if ( stat( FS_DIR_LOCATION, &status1 ) )
    {
        __gDAFileSystemListTime1.tv_sec  = 0;
        __gDAFileSystemListTime1.tv_nsec = 0;
    }

    if ( stat( ___FS_DEFAULT_DIR, &status2 ) )
    {
        __gDAFileSystemListTime2.tv_sec  = 0;
        __gDAFileSystemListTime2.tv_nsec = 0;
    }

    if ( __gDAFileSystemListTime1.tv_sec  != status1.st_mtimespec.tv_sec  ||
         __gDAFileSystemListTime1.tv_nsec != status1.st_mtimespec.tv_nsec ||
         __gDAFileSystemListTime2.tv_sec  != status2.st_mtimespec.tv_sec  ||
         __gDAFileSystemListTime2.tv_nsec != status2.st_mtimespec.tv_nsec )
    {
        __gDAFileSystemListTime1.tv_sec  = status1.st_mtimespec.tv_sec;
        __gDAFileSystemListTime1.tv_nsec = status1.st_mtimespec.tv_nsec;
        __gDAFileSystemListTime2.tv_sec  = status2.st_mtimespec.tv_sec;
        __gDAFileSystemListTime2.tv_nsec = status2.st_mtimespec.tv_nsec;

        /*
         * Clear the file system list.
         */

        CFArrayRemoveAllValues( gDAFileSystemList );
        CFArrayRemoveAllValues( gDAFileSystemProbeList );

        /*
         * Build the file system list.
         */

        __DAFileSystemListRefresh( FS_DIR_LOCATION );
        __DAFileSystemListRefresh( ___FS_DEFAULT_DIR );

        /*
         * Order the probe list.
         */

        CFArraySortValues( gDAFileSystemProbeList,
                           CFRangeMake( 0, CFArrayGetCount( gDAFileSystemProbeList ) ),
                           __DAFileSystemProbeListCompare,
                           NULL );
    }
}
示例#2
0
static void
__show_service_protocols(SCNetworkServiceRef service, const char *prefix, Boolean skipEmpty)
{
	CFIndex		i;
	CFIndex		n;
	CFArrayRef	protocols;

	protocols = SCNetworkServiceCopyProtocols(service);
	if (protocols == NULL) {
		return;
	}

	n = CFArrayGetCount(protocols);
	if (n > 1) {
		CFMutableArrayRef	sorted;

		sorted = CFArrayCreateMutableCopy(NULL, 0, protocols);
		CFArraySortValues(sorted,
				  CFRangeMake(0, n),
				  _compare_protocols,
				  NULL);
		CFRelease(protocols);
		protocols = sorted;
	}

	for (i = 0; i < n; i++) {
		CFStringRef		description;
		SCNetworkProtocolRef	protocol;

		protocol = CFArrayGetValueAtIndex(protocols, i);
		description = _protocol_description(protocol, skipEmpty);
		if (description != NULL) {
			CFStringRef	protocolType;

			protocolType = SCNetworkProtocolGetProtocolType(protocol);
			SCPrint(TRUE, stdout,
				CFSTR("%s%@%*s : %@\n"),
				prefix,
				protocolType,
				(int)(sizeof("Interface") - CFStringGetLength(protocolType) - 1),
				"",
				description);
			CFRelease(description);
		}
	}

	CFRelease(protocols);
	return;
}
示例#3
0
static CFIndex CFURLEnumeratorPushURL(CFURLEnumeratorRef enumerator, CFURLRef url, CFErrorRef *error) {
    char path[PATH_MAX] = { 0 };
    CFStringRef urlPath = CFURLCopyPath(url);
    Boolean success = CFStringGetFileSystemRepresentation(urlPath, path, PATH_MAX);
    
    if (!success) {
        cocoaError(error, -1, url, urlPath);
        CFRelease(urlPath);
        return kCFNotFound;
    }

    DIR *dir = opendir(path);
    if (dir == NULL) {
        posixError(error, url, urlPath);
        CFRelease(urlPath);
        return kCFNotFound;
    }

    CFMutableArrayRef fileInfos = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);

    struct dirent *current = NULL;
    while ((current = readdir(dir)) != NULL) {
        if (strcmp(current->d_name, ".") == 0 || strcmp(current->d_name, "..") == 0) {
            continue;
        }
        CFMutableDictionaryRef fileInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFStringRef fileName = CFStringCreateWithBytes(kCFAllocatorDefault, current->d_name, strlen(current->d_name), kCFStringEncodingUTF8, false);
        CFDictionarySetValue(fileInfo, fileInfoNameKey, fileName);
        CFDictionarySetValue(fileInfo, fileInfoIsDirKey, current->d_type == DT_DIR ? kCFBooleanTrue : kCFBooleanFalse);
        CFArrayAppendValue(fileInfos, fileInfo);
        CFRelease(fileName);
        CFRelease(fileInfo);
    }

    CFArraySortValues(fileInfos, CFRangeMake(0, CFArrayGetCount(fileInfos)), _compareFileInfo, nil);
    CFArrayAppendValue(enumerator->urlStack, url);
    CFArrayAppendValue(enumerator->dirFileInfos, fileInfos);
    CFRelease(urlPath);
    CFRelease(fileInfos);
    closedir(dir);
    return CFArrayGetCount(enumerator->urlStack);
}
示例#4
0
void HIDRebuildDevices( void ) {
	// get the set of devices from the IOHID manager
	CFSetRef devCFSetRef = IOHIDManagerCopyDevices( gIOHIDManagerRef );

	if ( devCFSetRef ) {
		// if the existing array isn't empty...
		if ( gDeviceCFArrayRef ) {
			// release it
			CFRelease( gDeviceCFArrayRef );
		}
		// create an empty array
		gDeviceCFArrayRef = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks );
		// now copy the set to the array
		CFSetApplyFunction( devCFSetRef, CFSetApplierFunctionCopyToCFArray, ( void * ) gDeviceCFArrayRef );
		// now sort the array by location ID's
		CFIndex cnt = CFArrayGetCount( gDeviceCFArrayRef );
		CFArraySortValues( gDeviceCFArrayRef, CFRangeMake( 0, cnt ), CFDeviceArrayComparatorFunction, NULL );

		// and release the set we copied from the IOHID manager
		CFRelease( devCFSetRef );
	}
}   // HIDRebuildDevices
/**************************************************************************
 *                              open_joystick
 */
static BOOL open_joystick(joystick_t* joystick)
{
    CFIndex index;
    CFRange range;

    if (joystick->element)
        return TRUE;

    if (!device_main_elements)
    {
        find_osx_devices();
        if (!device_main_elements)
            return FALSE;
    }

    index = joystick - joysticks;
    if (index >= CFArrayGetCount(device_main_elements))
        return FALSE;

    joystick->element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, index);
    joystick->buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    collect_joystick_elements(joystick, joystick->element);

    /* Sort buttons into correct order */
    range.location = 0;
    range.length = CFArrayGetCount(joystick->buttons);
    CFArraySortValues(joystick->buttons, range, button_usage_comparator, NULL);
    if (range.length > 32)
    {
        /* Delete any buttons beyond the first 32 */
        range.location = 32;
        range.length -= 32;
        CFArrayReplaceValues(joystick->buttons, range, NULL, 0);
    }

    return TRUE;
}
示例#6
0
std::string getKextLinked(const void *value, const CFStringRef key) {
  std::string result;
  auto links = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)value, key);
  if (links == nullptr) {
    // Very core.
    return result;
  }

  CFIndex count = CFArrayGetCount(links);
  if (count == 0) {
    // Odd error case, there was a linked value, but an empty list.
    return result;
  }

  auto link_indexes = CFArrayCreateMutableCopy(NULL, count, links);
  CFArraySortValues(link_indexes,
                    CFRangeMake(0, count),
                    (CFComparatorFunction)CFNumberCompare,
                    NULL);

  for (int i = 0; i < count; i++) {
    int link;
    CFNumberGetValue((CFNumberRef)CFArrayGetValueAtIndex(link_indexes, i),
                     kCFNumberSInt32Type,
                     (void *)&link);

    if (i > 0) {
      result += " ";
    }

    result += TEXT(link);
  }

  CFRelease(link_indexes);
  // Return in kextstat format for linked extensions.
  return "<" + result + ">";
}
示例#7
0
SCNetworkServiceRef
SCNetworkSetCopySelectedVPNService(SCNetworkSetRef set)
{
	CFIndex			i;
	CFIndex			n;
	SCNetworkServiceRef	selected	= NULL;
	CFArrayRef		services;
	CFMutableArrayRef	services_vpn	= NULL;

	if (!isA_SCNetworkSet(set)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return NULL;
	}

	services = SCNetworkSetCopyServices(set);
	if (services != NULL) {
		n = CFArrayGetCount(services);
		for (i = 0; i < n; i++) {
			SCNetworkServiceRef	service;

			service = CFArrayGetValueAtIndex(services, i);
			if (!SCNetworkServiceGetEnabled(service)) {
				// if not enabled
				continue;
			}

			if (!_SCNetworkServiceIsVPN(service)) {
				// if not VPN service
				continue;
			}

			if (services_vpn == NULL) {
				services_vpn = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
			}
			CFArrayAppendValue(services_vpn, service);
		}

		CFRelease(services);
	}

	if (services_vpn == NULL) {
		// if no VPN services
		return NULL;
	}

	n = CFArrayGetCount(services_vpn);
	if (n > 1) {
		CFArrayRef		order;
		CFMutableArrayRef	sorted;

		order = SCNetworkSetGetServiceOrder(set);
		sorted = CFArrayCreateMutableCopy(NULL, 0, services_vpn);
		CFArraySortValues(sorted,
				  CFRangeMake(0, CFArrayGetCount(sorted)),
				  _SCNetworkServiceCompare,
				  (void *)order);
		CFRelease(services_vpn);
		services_vpn = sorted;
	}

#if	TARGET_OS_IPHONE
	if (n > 1) {
		CFStringRef	serviceID_prefs;

#define VPN_PREFERENCES	CFSTR("com.apple.mobilevpn")
#define VPN_SERVICE_ID	CFSTR("activeVPNID")

		CFPreferencesAppSynchronize(VPN_PREFERENCES);
		serviceID_prefs = CFPreferencesCopyAppValue(VPN_SERVICE_ID, VPN_PREFERENCES);
		if (serviceID_prefs != NULL) {
			for (i = 0; i < n; i++) {
				SCNetworkServiceRef	service;
				CFStringRef		serviceID;

				service = CFArrayGetValueAtIndex(services_vpn, i);
				serviceID = SCNetworkServiceGetServiceID(service);
				if (CFEqual(serviceID, serviceID_prefs)) {
					selected = service;
					CFRetain(selected);
					break;
				}

			}

			CFRelease(serviceID_prefs);
		}
	}
#endif	// TARGET_OS_IPHONE

	if (selected == NULL) {
		selected = CFArrayGetValueAtIndex(services_vpn, 0);
		CFRetain(selected);
	}

	CFRelease(services_vpn);
	return selected;
}
示例#8
0
static void __DAStagePeek( DADiskRef disk )
{
    /*
     * We commence the "peek" stage if the conditions are right.
     */

    CFMutableArrayRef candidates;

    candidates = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks );

    if ( candidates )
    {
        DASessionRef session;
        CFArrayRef   sessionList;
        CFIndex      sessionListCount;
        CFIndex      sessionListIndex;

        sessionList      = gDASessionList;
        sessionListCount = CFArrayGetCount( sessionList );

        for ( sessionListIndex = 0; sessionListIndex < sessionListCount; sessionListIndex++ )
        {
            DACallbackRef callback;
            CFArrayRef    callbackList;
            CFIndex       callbackListCount;
            CFIndex       callbackListIndex;
            
            session = ( void * ) CFArrayGetValueAtIndex( sessionList, sessionListIndex );

            callbackList      = DASessionGetCallbackRegister( session );
            callbackListCount = CFArrayGetCount( callbackList );

            for ( callbackListIndex = 0; callbackListIndex < callbackListCount; callbackListIndex++ )
            {
                callback = ( void * ) CFArrayGetValueAtIndex( callbackList, callbackListIndex );

                if ( DACallbackGetKind( callback ) == _kDADiskPeekCallback )
                {
                    CFArrayAppendValue( candidates, callback );
                }
            }
        }

        CFArraySortValues( candidates, CFRangeMake( 0, CFArrayGetCount( candidates ) ), __DAStagePeekCompare, NULL );

        /*
         * Commence the peek.
         */

        CFRetain( disk );

        DADiskSetContext( disk, candidates );

        DADiskSetState( disk, kDADiskStateStagedPeek, TRUE );

        DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

        __DAStagePeekCallback( NULL, disk );

        CFRelease( candidates );
    }
}
示例#9
0
__private_extern__
void
show_service(int argc, char **argv)
{
	SCNetworkInterfaceRef		interface;
	CFArrayRef			protocols;
	SCNetworkServiceRef		service;
	CFStringRef			serviceName;
	SCNetworkServicePrimaryRank	serviceRank;

	if (argc == 1) {
		service = _find_service(argv[0]);
	} else {
		if (net_service != NULL) {
			service = net_service;
		} else {
			SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
			return;
		}
	}

	if (service == NULL) {
		return;
	}

	SCPrint(TRUE, stdout, CFSTR("service id           = %@\n"), SCNetworkServiceGetServiceID(service));

	serviceName = SCNetworkServiceGetName(service);
	SCPrint(TRUE, stdout, CFSTR("name                 = %@\n"),
		(serviceName != NULL) ? serviceName : CFSTR(""));

	serviceRank = SCNetworkServiceGetPrimaryRank(service);
	switch (serviceRank) {
		case kSCNetworkServicePrimaryRankDefault :
			// nothing to report
			break;
		case kSCNetworkServicePrimaryRankFirst :
			SCPrint(TRUE, stdout, CFSTR("primary rank         = FIRST\n"));
			break;
		case kSCNetworkServicePrimaryRankLast :
			SCPrint(TRUE, stdout, CFSTR("primary rank         = LAST\n"));
			break;
		case kSCNetworkServicePrimaryRankNever :
			SCPrint(TRUE, stdout, CFSTR("primary rank         = NEVER\n"));
			break;
		case kSCNetworkServicePrimaryRankScoped :
			SCPrint(TRUE, stdout, CFSTR("primary rank         = SCOPED\n"));
			break;
		default :
			SCPrint(TRUE, stdout, CFSTR("primary rank         = %d\n"), serviceRank);
			break;
	}

	interface = SCNetworkServiceGetInterface(service);
	if (interface != NULL) {
		CFStringRef	interfaceName;

		interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface);
		if (interfaceName != NULL) {
			CFRetain(interfaceName);
		} else {
			interfaceName = _interface_description(interface);
		}
		if (interfaceName != NULL) {
			SCPrint(TRUE, stdout, CFSTR("interface            = %@\n"), interfaceName);
			CFRelease(interfaceName);
		}
	} else {
		SCPrint(TRUE, stdout, CFSTR("\n  No interface!\n\n"));
	}

	protocols = SCNetworkServiceCopyProtocols(service);
	if (protocols != NULL) {
		CFIndex	n;

		n = CFArrayGetCount(protocols);
		if (n > 1) {
			CFMutableArrayRef	sorted;

			sorted = CFArrayCreateMutableCopy(NULL, 0, protocols);
			CFArraySortValues(sorted,
					  CFRangeMake(0, n),
					  _compare_protocols,
					  NULL);
			CFRelease(protocols);
			protocols = sorted;
		}

		if (n > 0) {
			CFIndex	i;

			SCPrint(TRUE, stdout, CFSTR("configured protocols = "));
			for (i = 0; i < n; i++) {
				SCNetworkProtocolRef	protocol;

				protocol = CFArrayGetValueAtIndex(protocols, i);
				SCPrint(TRUE, stdout, CFSTR("%s%@"),
					(i == 0) ? "" : ", ",
					SCNetworkProtocolGetProtocolType(protocol));
			}
			SCPrint(TRUE, stdout, CFSTR("\n"));

			__show_service_protocols(service, "  ", FALSE);
		} else {
			SCPrint(TRUE, stdout, CFSTR("no configured protocols\n"));
		}

		CFRelease(protocols);
	}

	if (_sc_debug) {
		SCPrint(TRUE, stdout, CFSTR("\n%@\n"), service);
	}

	return;
}
示例#10
0
文件: SCD.c 项目: 010001111/darling
CFStringRef
_SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
{
#ifdef	ENABLE_SC_FORMATTING
	CFMutableDictionaryRef	nFormatOptions;
	CFStringRef		prefix1;
	CFStringRef		prefix2;
	CFTypeID		type	= CFGetTypeID(cf);

	if (!formatOptions ||
	    !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX1"), (const void **)&prefix1)) {
		prefix1 = CFSTR("");
	}

	if (type == CFStringGetTypeID()) {
		return CFStringCreateWithFormat(NULL,
						formatOptions,
						CFSTR("%@%@"),
						prefix1,
						cf);
	}

	if (type == CFBooleanGetTypeID()) {
		return CFStringCreateWithFormat(NULL,
						formatOptions,
						CFSTR("%@%s"),
						prefix1,
						CFBooleanGetValue(cf) ? "TRUE" : "FALSE");
	}

	if (type == CFDataGetTypeID()) {
		const uint8_t		*data;
		CFIndex			dataLen;
		CFIndex			i;
		CFMutableStringRef	str;

		str = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(str, formatOptions, CFSTR("%@<data> 0x"), prefix1);

		data    = CFDataGetBytePtr(cf);
		dataLen = CFDataGetLength(cf);
		for (i = 0; i < dataLen; i++) {
			CFStringAppendFormat(str, NULL, CFSTR("%02x"), data[i]);
		}

		return str;
	}

	if (type == CFNumberGetTypeID()) {
		return CFStringCreateWithFormat(NULL,
						formatOptions,
						CFSTR("%@%@"),
						prefix1,
						cf);
	}

	if (type == CFDateGetTypeID()) {
		CFCalendarRef	calendar;
		CFStringRef	str;
		CFTimeZoneRef	tz;
		int		MM, DD, YYYY, hh, mm, ss;

		calendar = CFCalendarCreateWithIdentifier(NULL, kCFGregorianCalendar);
		tz = CFTimeZoneCopySystem();
		CFCalendarSetTimeZone(calendar, tz);
		CFRelease(tz);
		CFCalendarDecomposeAbsoluteTime(calendar,
						CFDateGetAbsoluteTime(cf),
						"MdyHms",
						&MM, &DD, &YYYY, &hh, &mm, &ss);
		CFRelease(calendar);

		str = CFStringCreateWithFormat(NULL,
					       formatOptions,
					       CFSTR("%@%02d/%02d/%04d %02d:%02d:%02d"),
					       prefix1,
					       MM, DD, YYYY, hh, mm, ss);
		return str;
	}

	if ((formatOptions == NULL) ||
	    !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) {
		prefix2 = prefix1;
	}

	if (formatOptions != NULL) {
		nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions);
	} else {
		nFormatOptions = CFDictionaryCreateMutable(NULL,
							   0,
							   &kCFTypeDictionaryKeyCallBacks,
							   &kCFTypeDictionaryValueCallBacks);
	}
	assert(nFormatOptions != NULL);

#define	N_QUICK	32

	if (type == CFArrayGetTypeID()) {
		const void *		elements_q[N_QUICK];
		const void **		elements	= elements_q;
		CFIndex			i;
		CFIndex			nElements;
		CFMutableStringRef	str;

		str = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(str, formatOptions, CFSTR("%@<array> {"), prefix1);

		nElements = CFArrayGetCount(cf);
		if (nElements > 0) {
			if (nElements > (CFIndex)(sizeof(elements_q)/sizeof(CFTypeRef)))
				elements  = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
			CFArrayGetValues(cf, CFRangeMake(0, nElements), elements);
			for (i = 0; i < nElements; i++) {
				CFMutableStringRef	nPrefix1;
				CFMutableStringRef	nPrefix2;
				CFStringRef		nStr;
				CFStringRef		vStr;

				nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), i);

				nPrefix1 = CFStringCreateMutable(NULL, 0);
				CFStringAppendFormat(nPrefix1,
						     formatOptions,
						     CFSTR("%@  %@ : "),
						     prefix2,
						     nStr);
				nPrefix2 = CFStringCreateMutable(NULL, 0);
				CFStringAppendFormat(nPrefix2,
						     formatOptions,
						     CFSTR("%@  "),
						     prefix2);

				CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1);
				CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2);
				CFRelease(nPrefix1);
				CFRelease(nPrefix2);
				CFRelease(nStr);

				vStr = _SCCopyDescription((CFTypeRef)elements[i], nFormatOptions);
				CFStringAppendFormat(str,
						     formatOptions,
						     CFSTR("\n%@"),
						     vStr);
				CFRelease(vStr);
			}
			if (elements != elements_q) CFAllocatorDeallocate(NULL, elements);
		}
		CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);

		CFRelease(nFormatOptions);
		return str;
	}

	if (type == CFDictionaryGetTypeID()) {
		const void *		keys_q[N_QUICK];
		const void **		keys	= keys_q;
		CFIndex			i;
		CFIndex			nElements;
		CFMutableStringRef	nPrefix1;
		CFMutableStringRef	nPrefix2;
		CFMutableStringRef	str;

		str = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(str, formatOptions, CFSTR("%@<dictionary> {"), prefix1);

		nElements = CFDictionaryGetCount(cf);
		if (nElements > 0) {
			CFComparatorFunction	compFunc	= NULL;
			CFMutableArrayRef	sortedKeys;

			if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
				keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
			}
			CFDictionaryGetKeysAndValues(cf, keys, NULL);

			sortedKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
			for (i = 0; i < nElements; i++) {
				CFArrayAppendValue(sortedKeys, (CFStringRef)keys[i]);
			}

			if (isA_CFString(keys[0])) {
				compFunc = (CFComparatorFunction)CFStringCompare;
			}
			else if (isA_CFNumber(keys[0])) {
				compFunc = (CFComparatorFunction)CFNumberCompare;
			}
			else if (isA_CFDate(keys[0])) {
				compFunc = (CFComparatorFunction)CFDateCompare;
			}

			if (compFunc != NULL) {
				CFArraySortValues(sortedKeys,
						  CFRangeMake(0, nElements),
						  compFunc,
						  NULL);
			}

			for (i = 0; i < nElements; i++) {
				CFStringRef		key;
				CFStringRef		kStr;
				CFTypeRef		val;
				CFStringRef		vStr;

				key  = CFArrayGetValueAtIndex(sortedKeys, i);
				kStr = _SCCopyDescription((CFTypeRef)key, NULL);

				nPrefix1 = CFStringCreateMutable(NULL, 0);
				CFStringAppendFormat(nPrefix1,
						     formatOptions,
						     CFSTR("%@  %@ : "),
						     prefix2,
						     kStr);
				nPrefix2 = CFStringCreateMutable(NULL, 0);
				CFStringAppendFormat(nPrefix2,
						     formatOptions,
						     CFSTR("%@  "),
						     prefix2);

				CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1);
				CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2);
				CFRelease(nPrefix1);
				CFRelease(nPrefix2);
				CFRelease(kStr);

				val  = CFDictionaryGetValue(cf, key);
				vStr = _SCCopyDescription((CFTypeRef)val, nFormatOptions);
				CFStringAppendFormat(str,
						     formatOptions,
						     CFSTR("\n%@"),
						     vStr);
				CFRelease(vStr);
			}

			CFRelease(sortedKeys);

			if (keys != keys_q) {
				CFAllocatorDeallocate(NULL, keys);
			}
		}
		CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);

		CFRelease(nFormatOptions);
		return str;
	}

	CFRelease(nFormatOptions);
#endif	/* ENABLE_SC_FORMATTING */

	return CFStringCreateWithFormat(NULL,
					formatOptions,
					CFSTR("%@%@"),
					prefix1,
					cf);
}
extern pascal OSStatus MoreSCCreatePortArray(CFArrayRef *portArray)
	// See comment in header.
{
    kern_return_t		err;
    CFMutableArrayRef	result;
	CFStringRef 		keys[2];
	CFStringRef 		values[2];

	assert( portArray != NULL);
	assert(*portArray == NULL);
	
	result = NULL;
	    
	err = CFQArrayCreateMutable(&result);
	if (err == 0 && gMasterPort == 0) {
	    err = IOMasterPort(bootstrap_port, &gMasterPort);
	}
	
	// Ethernet-like devices (includes AirPort)
	
    if (err == 0) {
		err = AddMatchingDevicesToArray(gMasterPort, IOServiceMatching(kIOEthernetInterfaceClass), 
										EthernetDeviceToDictProc, NULL, result);
    }
    
    // Set up common key/value pairs for the next two calls.
    
	  keys[0] = CFSTR(kIOProviderClassKey);
	values[0] = CFSTR(kIOSerialBSDServiceValue);
	  keys[1] = CFSTR(kIOSerialBSDTypeKey);

	// Modem devices
	
    if (err == 0) {
		values[1] = CFSTR(kIOSerialBSDModemType);

		err = AddMatchingDevicesToArray(gMasterPort, CFDictionaryCreate(NULL, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), 
										ModemOrSerialDeviceToDictProc, NULL, result);
    }
    
    // Serial devices (includes IrDA)
    
    if (err == 0) {
		values[1] = CFSTR(kIOSerialBSDRS232Type);

		err = AddMatchingDevicesToArray(gMasterPort, CFDictionaryCreate(NULL, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), 
										ModemOrSerialDeviceToDictProc, NULL, result);
    }
    if (err == 0) {
	    CFArraySortValues(result, CFRangeMake( 0, CFArrayGetCount( result )), PortSorter, NULL);
	}
    
    // Clean up.

	if (err != 0) {
		CFQRelease(result);
		result = NULL;
	}
	*portArray = result;

	assert( (err == noErr) == (*portArray != NULL) );
	
	// This is cheesy.  We cast the kern_return_t directly to an OSStatus.
	
	return err;    
}
示例#12
0
unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
    unsigned int returncode = 1;
    int numModes = 0;
    int i;

    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
    if (allModes == NULL) {
        returncode = 0;
    }

    numModes = CFArrayGetCount(allModes);

    // sort the array of display modes
    CFMutableArrayRef allModesSorted =  CFArrayCreateMutableCopy(
                                          kCFAllocatorDefault,
                                          numModes,
                                          allModes
                                        );

    CFArraySortValues(
        allModesSorted,
        CFRangeMake(0, CFArrayGetCount(allModesSorted)),
        (CFComparatorFunction) _compareCFDisplayModes,
        NULL
    ); 

#ifndef LIST_DEBUG
    if(displayNum != 0)
        printf("\n\n");
    printf("Available Modes on Display %d\n", displayNum);
#endif

    CGDisplayModeRef mode;

    int modesPerColumn = numModes / MODES_PER_LINE;

    for (i = 0; (i < numModes) && returncode; i++) {
        int rowNumber = (i / MODES_PER_LINE);
        int idxDisplayMode = (i % MODES_PER_LINE) * modesPerColumn + rowNumber;

        // if there are an even number of display modes to display,
        // the last mode must have it's index decremented by 1
        idxDisplayMode = MIN(idxDisplayMode, numModes - 1);

        mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModesSorted, idxDisplayMode);

        // This formatting is functional but it ought to be done less poorly.
#ifndef LIST_DEBUG
        if (i % MODES_PER_LINE == 0) {
            printf("  ");
        } else {
            printf("\t");
        }

        char modestr [50];
        sprintf(modestr, "%4lux%4lux%lu@%.0f",
               CGDisplayModeGetWidth(mode),
               CGDisplayModeGetHeight(mode),
               bitDepth(mode),
               CGDisplayModeGetRefreshRate(mode));
        printf("%-20s ", modestr);

        if(i % MODES_PER_LINE == MODES_PER_LINE - 1)
            printf("\n");
#else
        uint32_t ioflags = CGDisplayModeGetIOFlags(mode);
        printf("display: %d %4lux%4lux%2lu@%.0f usable:%u ioflags:%4x valid:%u safe:%u default:%u",
                displayNum,
                CGDisplayModeGetWidth(mode),
                CGDisplayModeGetHeight(mode),
                bitDepth(mode),
                CGDisplayModeGetRefreshRate(mode),
                CGDisplayModeIsUsableForDesktopGUI(mode),
                ioflags,
                ioflags & kDisplayModeValidFlag ?1:0,
                ioflags & kDisplayModeSafeFlag ?1:0,
                ioflags & kDisplayModeDefaultFlag ?1:0 );
        printf(" safety:%u alwaysshow:%u nevershow:%u notresize:%u requirepan:%u int:%u simul:%u",
                ioflags & kDisplayModeSafetyFlags ?1:0,
                ioflags & kDisplayModeAlwaysShowFlag ?1:0,
                ioflags & kDisplayModeNeverShowFlag ?1:0,
                ioflags & kDisplayModeNotResizeFlag ?1:0,
                ioflags & kDisplayModeRequiresPanFlag ?1:0,
                ioflags & kDisplayModeInterlacedFlag ?1:0,
                ioflags & kDisplayModeSimulscanFlag ?1:0 );
        printf(" builtin:%u notpreset:%u stretched:%u notgfxqual:%u valagnstdisp:%u tv:%u vldmirror:%u\n",
                ioflags & kDisplayModeBuiltInFlag ?1:0,
                ioflags & kDisplayModeNotPresetFlag ?1:0,
                ioflags & kDisplayModeStretchedFlag ?1:0,
                ioflags & kDisplayModeNotGraphicsQualityFlag ?1:0,
                ioflags & kDisplayModeValidateAgainstDisplay ?1:0,
                ioflags & kDisplayModeTelevisionFlag ?1:0,
                ioflags & kDisplayModeValidForMirroringFlag ?1:0 );
#endif
    }

    CFRelease(allModes);
    CFRelease(allModesSorted);

    return returncode;
}
示例#13
0
__private_extern__
void
show_services(int argc, char **argv)
{
	CFIndex	i;
	CFIndex	n;

	if (prefs == NULL) {
		SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
		return;
	}

	if (argc == 1) {
		if (services != NULL) CFRelease(services);
		services = SCNetworkServiceCopyAll(prefs);
	} else {
		if (net_set == NULL) {
			SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
			return;
		}

		if (services != NULL) CFRelease(services);
		services = SCNetworkSetCopyServices(net_set);
		n = (services != NULL) ? CFArrayGetCount(services) : 0;
		if (n > 1) {
			CFArrayRef		order;
			CFMutableArrayRef	sorted;

			order  = SCNetworkSetGetServiceOrder(net_set);
			sorted = CFArrayCreateMutableCopy(NULL, 0, services);
			CFArraySortValues(sorted,
					  CFRangeMake(0, CFArrayGetCount(sorted)),
					  _SCNetworkServiceCompare,
					  (void *)order);
			CFRelease(services);
			services = sorted;
		}
	}

	if (services == NULL) {
		SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
		return;
	}

	n = CFArrayGetCount(services);
	for (i = 0; i < n; i++) {
		SCNetworkServiceRef	service;
		CFStringRef		serviceName;
		CFStringRef		serviceID;

		service     = CFArrayGetValueAtIndex(services, i);
		serviceID   = SCNetworkServiceGetServiceID(service);
		serviceName = SCNetworkServiceGetName(service);
		if (serviceName == NULL) serviceName = CFSTR("");

		SCPrint(TRUE, stdout, CFSTR("%c%2ld: %@%-*s (%@)%s\n"),
			((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
			i + 1,
			serviceName,
			(int)(30 - CFStringGetLength(serviceName)),
			" ",
			serviceID,
			SCNetworkServiceGetEnabled(service) ? "" : " *DISABLED*");

		__show_service_interface(service, "       Interface : ");
		__show_service_protocols(service, "       ", TRUE);
	}

	return;
}
示例#14
0
extern OSStatus MoreSCCreateCCLArray(CFArrayRef *result, CFIndex *indexOfDefaultCCL)
	// See comment in header.
{
	OSStatus 			err;
	CFMutableArrayRef	localResult;
	UInt32   			domainIndex;
	FSRef				folderRef;
	static const SInt16 kFolderDomains[] = {kUserDomain, kNetworkDomain, kLocalDomain, kSystemDomain, 0};
	
	assert( result != NULL);
	assert(*result == NULL);
	
	// Create an array containing the names of the CCLs from the Modem Scripts 
	// folder in each domain.

	localResult = NULL;
		
	err = CFQArrayCreateMutable(&localResult);
	if (err == noErr) {
		UInt32 scannedFolders;
		
		scannedFolders = 0;
		domainIndex = 0;
		do {
			err = FSFindFolder(kFolderDomains[domainIndex], kModemScriptsFolderType, false, &folderRef);
			if (err != noErr) {
				// If we can't find the folder in this domain, just ignore the domain.
				err = noErr;
			} else {
				scannedFolders += 1;
				// If we found the folder, add each CCL in it to the array.
				err = AddCCLsInFolderToArray(&folderRef, localResult);
			}
			domainIndex += 1;
		} while (err == noErr && kFolderDomains[domainIndex] != 0);
		
		// Testing reveals that under certain circumstances, the above loop 
		// will never find any folders.  The specific case I saw was on 
		// Mac OS 9.1 with CarbonLib 1.6 when running the application off 
		// the non-boot volume.  So, if FSFindFolder never returns any 
		// folders in the domains we looped over above, let's do it the old 
		// way and call FSFindFolder with kOnSystemDisk.
		//
		// I didn't file a bug against FSFindFolder because traditional Mac OS 
		// bugs are no longer being fixed at this time.
		// -- Quinn, 10 Dec 2002
		
		if ( (err == noErr) && (scannedFolders == 0) ) {
			if (FSFindFolder(kOnSystemDisk, kModemScriptsFolderType, false, &folderRef) == noErr) {
				err = AddCCLsInFolderToArray(&folderRef, localResult);
			}
		}
	}
	
	// Sort the resulting array and delete any duplicates.
	
	if (err == noErr) {
		CFIndex cursor;
		
		CFArraySortValues(localResult, CFRangeMake(0, CFArrayGetCount(localResult)), 
						  (CFComparatorFunction) CFStringCompare, (void *) kMyStringCompareOptions);
		
		cursor = 1;
		while (cursor < CFArrayGetCount(localResult)) {
			if ( CFEqual(CFArrayGetValueAtIndex(localResult, cursor), CFArrayGetValueAtIndex(localResult, cursor - 1)) ) {
				CFArrayRemoveValueAtIndex(localResult, cursor);
			} else {
				cursor += 1;
			}
		}
	}
	
	// Find the index of the default CCL (or use the first CCL if the default 
	// isn't found).  The array is already sorted for user presentation, so 
	// we can use CFArrayBSearchValues rather than searching by hand.  This 
	// might even be a relevant speed increase because the number of CCLs can 
	// range into the hundreds.
	
	if (err == noErr && indexOfDefaultCCL != NULL) {
		CFStringRef defaultCCLName;
		CFIndex     itemIndex;
		
        defaultCCLName = MoreSCCopyDefaultCCL();

		itemIndex = CFArrayBSearchValues(localResult, CFRangeMake(0, CFArrayGetCount(localResult)), 
											defaultCCLName, 
											(CFComparatorFunction) CFStringCompare, (void *) kMyStringCompareOptions);
		// itemIndex is either:
		//
		// o pointing directly at the correct element, if an exact match is found, or 
		//
		// o if no exact match is found, pointing after the element that's immediately 
		//   less than defaultCCLName
		//
		// So, to confirm that we have the default script we check that the item is in 
		// bounds and that its value matches defaultCCLName.  If either of these 
		// checks fails, we return the index of the first CCL.
		
		if ( (itemIndex < CFArrayGetCount(localResult)) 
				&& (CFStringCompare(defaultCCLName, 
									(CFStringRef) CFArrayGetValueAtIndex(localResult, itemIndex), 
									kMyStringCompareOptions) == kCFCompareEqualTo)) {
			*indexOfDefaultCCL = itemIndex;
		} else {
			*indexOfDefaultCCL = 0;
		}
        
        CFQRelease(defaultCCLName);
	}

	// Clean up.
	
	if (err != noErr) {
		CFQRelease(localResult);
		localResult = NULL;
	}
	*result = localResult;
	
	assert( (err == noErr) == (*result != NULL) );
	assert( 	(err != noErr) 							// either we got an error
				 || (indexOfDefaultCCL == NULL) 				// or the user didn't ask for the default CCL
				 || (CFArrayGetCount(*result) == 0) 		// or there are no CCLs
				 || (*indexOfDefaultCCL >= 0 && *indexOfDefaultCCL < CFArrayGetCount(*result)) );
				 											// or the default CCL we're returning is in bounds

	return err;
}
示例#15
0
CFDictionaryRef APCreateDictionaryForLicenseData(CFDataRef data)
{
    if (!rsaKey->n || !rsaKey->e)
        return NULL;
    
    // Make the property list from the data
    CFStringRef errorString = NULL;
    CFPropertyListRef propertyList;
    propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListMutableContainers, &errorString);
    if (errorString || CFDictionaryGetTypeID() != CFGetTypeID(propertyList) || !CFPropertyListIsValid(propertyList, kCFPropertyListXMLFormat_v1_0)) {
        if (propertyList)
            CFRelease(propertyList);
        return NULL;
    }
    
    // Load the signature
    CFMutableDictionaryRef licenseDictionary = (CFMutableDictionaryRef)propertyList;
    if (!CFDictionaryContainsKey(licenseDictionary, CFSTR("Signature"))) {
        CFRelease(licenseDictionary);
        return NULL;
    }
    
    CFDataRef sigData = CFDictionaryGetValue(licenseDictionary, CFSTR("Signature"));
	CFIndex sigDataLength = CFDataGetLength(sigData);
	UInt8 sigBytes[sigDataLength];
    CFDataGetBytes(sigData, CFRangeMake(0, sigDataLength), sigBytes);
    CFDictionaryRemoveValue(licenseDictionary, CFSTR("Signature"));
    
    // Decrypt the signature
	int checkDigestMaxSize = RSA_size(rsaKey)-11;
    unsigned char checkDigest[checkDigestMaxSize];
    if (RSA_public_decrypt((int) sigDataLength, sigBytes, checkDigest, rsaKey, RSA_PKCS1_PADDING) != SHA_DIGEST_LENGTH) {
        CFRelease(licenseDictionary);
        return NULL;
    }
    
    // Get the license hash
    CFMutableStringRef hashCheck = CFStringCreateMutable(kCFAllocatorDefault,0);
    int hashIndex;
    for (hashIndex = 0; hashIndex < SHA_DIGEST_LENGTH; hashIndex++)
        CFStringAppendFormat(hashCheck, nil, CFSTR("%02x"), checkDigest[hashIndex]);
    APSetHash(hashCheck);
    CFRelease(hashCheck);
    
    if (blacklist && (CFArrayContainsValue(blacklist, CFRangeMake(0, CFArrayGetCount(blacklist)), hash) == true))
        return NULL;
    
    // Get the number of elements
    CFIndex count = CFDictionaryGetCount(licenseDictionary);
    // Load the keys and build up the key array
    CFMutableArrayRef keyArray = CFArrayCreateMutable(kCFAllocatorDefault, count, NULL);
    CFStringRef keys[count];
    CFDictionaryGetKeysAndValues(licenseDictionary, (const void**)&keys, NULL);
    int i;
    for (i = 0; i < count; i++)
        CFArrayAppendValue(keyArray, keys[i]);
    
    // Sort the array
    int context = kCFCompareCaseInsensitive;
    CFArraySortValues(keyArray, CFRangeMake(0, count), (CFComparatorFunction)CFStringCompare, &context);
    
    // Setup up the hash context
    SHA_CTX ctx;
    SHA1_Init(&ctx);
    // Convert into UTF8 strings
    for (i = 0; i < count; i++)
    {
        char *valueBytes;
        CFIndex valueLengthAsUTF8;
        CFStringRef key = CFArrayGetValueAtIndex(keyArray, i);
        CFStringRef value = CFDictionaryGetValue(licenseDictionary, key);
        
        // Account for the null terminator
        valueLengthAsUTF8 = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), kCFStringEncodingUTF8) + 1;
        valueBytes = (char *)malloc(valueLengthAsUTF8);
        CFStringGetCString(value, valueBytes, valueLengthAsUTF8, kCFStringEncodingUTF8);
        SHA1_Update(&ctx, valueBytes, strlen(valueBytes));
        free(valueBytes);
    }
    unsigned char digest[SHA_DIGEST_LENGTH];
    SHA1_Final(digest, &ctx);
    
    if (keyArray != NULL)
        CFRelease(keyArray);
    
    // Check if the signature is a match    
    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
        if (checkDigest[i] ^ digest[i]) {
            CFRelease(licenseDictionary);
            return NULL;
        }
    }
    
    // If it's a match, we return the dictionary; otherwise, we never reach this
    return licenseDictionary;
}
示例#16
0
size_t der_sizeof_dictionary(CFDictionaryRef dict, CFErrorRef *error)
{
    struct size_context context = { .success = true, .size = 0, .error = error };

    
    CFDictionaryApplyFunction(dict, add_key_value_size, &context);
    
    if (!context.success)
        return 0;

    return ccder_sizeof(CCDER_CONSTRUCTED_SET, context.size);
}

static uint8_t* der_encode_key_value(CFPropertyListRef key, CFPropertyListRef value, CFErrorRef *error,
                                     const uint8_t* der, uint8_t *der_end)
{
    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
           der_encode_plist(key, error, der,
           der_encode_plist(value, error, der, der_end)));
}

struct encode_context {
    bool         success;
    CFErrorRef * error;
    CFMutableArrayRef list;
    CFAllocatorRef allocator;
};

static void add_sequence_to_array(const void *key_void, const void *value_void, void *context_void)
{
    struct encode_context *context = (struct encode_context *) context_void;
    if (context->success) {
        CFTypeRef key = (CFTypeRef) key_void;
        CFTypeRef value = (CFTypeRef) value_void;

        size_t der_size = der_sizeof_key_value(key, value, context->error);
        if (der_size == 0) {
            context-> success = false;
        } else {
            CFMutableDataRef encoded_kv = CFDataCreateMutable(context->allocator, der_size);
            CFDataSetLength(encoded_kv, der_size);

            uint8_t* const encode_begin = CFDataGetMutableBytePtr(encoded_kv);
            uint8_t* encode_end = encode_begin + der_size;

            encode_end = der_encode_key_value(key, value, context->error, encode_begin, encode_end);

            if (encode_end != NULL) {
                CFDataDeleteBytes(encoded_kv, CFRangeMake(0, (encode_end - encode_begin)));
                CFArrayAppendValue(context->list, encoded_kv);
            } else {
                context-> success = false;
            }

            CFReleaseNull(encoded_kv);
        }
    }
}

static CFComparisonResult cfdata_compare_contents(const void *val1, const void *val2, void *context __unused)
{
    return CFDataCompare((CFDataRef) val1, (CFDataRef) val2);
}


uint8_t* der_encode_dictionary(CFDictionaryRef dictionary, CFErrorRef *error,
                               const uint8_t *der, uint8_t *der_end)
{
    CFMutableArrayRef elements = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    
    struct encode_context context = { .success = true, .error = error, .list = elements };
    CFDictionaryApplyFunction(dictionary, add_sequence_to_array, &context);
    
    if (!context.success) {
        CFReleaseNull(elements);
        return NULL;
    }
    
    CFRange allOfThem = CFRangeMake(0, CFArrayGetCount(elements));

    CFArraySortValues(elements, allOfThem, cfdata_compare_contents, NULL);

    uint8_t* original_der_end = der_end;

    for(CFIndex position = CFArrayGetCount(elements); position > 0;) {
        --position;
        CFDataRef data = CFArrayGetValueAtIndex(elements, position);
        der_end = ccder_encode_body(CFDataGetLength(data), CFDataGetBytePtr(data), der, der_end);
    }

    CFReleaseNull(elements);

    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SET, original_der_end, der, der_end);

}
示例#17
0
static void iohidmanager_hid_device_add(void *data, IOReturn result,
      void* sender, IOHIDDeviceRef device)
{
   int i;
   IOReturn ret;
   uint16_t dev_vid, dev_pid;
   CFArrayRef elements_raw;
   int count;
   CFMutableArrayRef elements;
   CFRange range;
   bool found_axis[6] =
   { false, false, false, false, false, false };
   apple_input_rec_t *tmp                   = NULL;
   apple_input_rec_t *tmpButtons            = NULL;
   apple_input_rec_t *tmpAxes               = NULL;
   iohidmanager_hid_t                  *hid = (iohidmanager_hid_t*)
      hid_driver_get_data();
   struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)
      calloc(1, sizeof(*adapter));

   if (!adapter)
      return;
   if (!hid)
      goto error;

   adapter->handle        = device;

   ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);

   if (ret != kIOReturnSuccess)
      goto error;

   /* Move the device's run loop to this thread. */
   IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
         kCFRunLoopCommonModes);
   IOHIDDeviceRegisterRemovalCallback(device,
         iohidmanager_hid_device_remove, adapter);

#ifndef IOS
   iohidmanager_hid_device_get_product_string(device, adapter->name,
         sizeof(adapter->name));
#endif

   dev_vid = iohidmanager_hid_device_get_vendor_id  (device);
   dev_pid = iohidmanager_hid_device_get_product_id (device);

   adapter->slot = pad_connection_pad_init(hid->slots,
         adapter->name, dev_vid, dev_pid, adapter,
         &iohidmanager_hid);

   if (adapter->slot == -1)
      goto error;

   if (pad_connection_has_interface(hid->slots, adapter->slot))
      IOHIDDeviceRegisterInputReportCallback(device,
            adapter->data + 1, sizeof(adapter->data) - 1,
            iohidmanager_hid_device_report, adapter);
   else
      IOHIDDeviceRegisterInputValueCallback(device,
            iohidmanager_hid_device_input_callback, adapter);

   if (string_is_empty(adapter->name))
      goto error;

   /* scan for buttons, axis, hats */
   elements_raw = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
   count        = (int)CFArrayGetCount(elements_raw);
   elements     = CFArrayCreateMutableCopy(
         kCFAllocatorDefault,(CFIndex)count,elements_raw);
   range        = CFRangeMake(0,count);

   CFArraySortValues(elements,
         range, iohidmanager_sort_elements, NULL);

   for (i = 0; i < count; i++)
   {
      IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);

      if (!element)
         continue;

      IOHIDElementType type = IOHIDElementGetType(element);
      uint32_t page         = (uint32_t)IOHIDElementGetUsagePage(element);
      uint32_t use          = (uint32_t)IOHIDElementGetUsage(element);
      uint32_t cookie       = (uint32_t)IOHIDElementGetCookie(element);

      int detected_button = 0;

      switch (page)
      {
         case kHIDPage_GenericDesktop:
            switch (type)
            {
               case kIOHIDElementTypeCollection:
               case kIOHIDElementTypeInput_ScanCodes:
               case kIOHIDElementTypeFeature:
               case kIOHIDElementTypeInput_Button:
               case kIOHIDElementTypeOutput:
               case kIOHIDElementTypeInput_Axis:
                  /* TODO/FIXME */
                  break;
               case kIOHIDElementTypeInput_Misc:
                  switch (use)
                  {
                     case kHIDUsage_GD_Hatswitch:
                        {
                           /* as far as I can tell, OSX only reports one Hat */
                           apple_input_rec_t *hat = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
                           hat->id                = 0;
                           hat->cookie            = (IOHIDElementCookie)cookie;
                           hat->next              = NULL;
                           adapter->hats          = hat;
                        }
                        break;
                     default:
                        {
                           uint32_t i = 0;
                           static const uint32_t axis_use_ids[6] =
                           { 48, 49, 51, 52, 50, 53 };

                           while (i < 6 && axis_use_ids[i] != use)
                              i++;

                           if (i < 6)
                           {

                              apple_input_rec_t *axis = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
                              axis->id                = i;
                              axis->cookie            = (IOHIDElementCookie)cookie;
                              axis->next              = NULL;

                              if(iohidmanager_check_for_id(adapter->axes,i))
                              {
                                 /* axis ID already exists, save to tmp for appending later */
                                 if(tmpAxes)
                                    iohidmanager_append_record(tmpAxes, axis);
                                 else
                                    tmpAxes = axis;
                              }
                              else
                              {
                                 found_axis[axis->id] = true;
                                 if(adapter->axes)
                                    iohidmanager_append_record(adapter->axes, axis);
                                 else
                                    adapter->axes = axis;
                              }
                           }
                           else
                              detected_button = 1;
                        }
                        break;
                  }
                  break;
            }
            break;
         case kHIDPage_Consumer:
         case kHIDPage_Button:
            switch (type)
            {
               case kIOHIDElementTypeCollection:
               case kIOHIDElementTypeFeature:
               case kIOHIDElementTypeInput_ScanCodes:
               case kIOHIDElementTypeInput_Axis:
               case kIOHIDElementTypeOutput:
                  /* TODO/FIXME */
                  break;
               case kIOHIDElementTypeInput_Misc:
               case kIOHIDElementTypeInput_Button:
                  detected_button = 1;
                  break;
            }
            break;
      }

      if (detected_button)
      {
         apple_input_rec_t *btn = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
         btn->id                = (uint32_t)use;
         btn->cookie            = (IOHIDElementCookie)cookie;
         btn->next              = NULL;

         if(iohidmanager_check_for_id(adapter->buttons,btn->id))
         {
            if(tmpButtons)
               iohidmanager_append_record_ordered(&tmpButtons, btn);
            else
               tmpButtons = btn;
         }
         else
         {
            if(adapter->buttons)
               iohidmanager_append_record_ordered(&adapter->buttons, btn);
            else
               adapter->buttons = btn;
         }
      }
   }

   /* take care of buttons/axes with duplicate 'use' values */
   for (i = 0; i < 6; i++)
   {
      if(found_axis[i] == false && tmpAxes)
      {
         apple_input_rec_t *next = tmpAxes->next;
         tmpAxes->id             = i;
         tmpAxes->next           = NULL;
         iohidmanager_append_record(adapter->axes, tmpAxes);
         tmpAxes = next;
      }
   }

   tmp = adapter->buttons;

   if (tmp)
   {
      while(tmp->next)
         tmp = tmp->next;
   }

   while(tmpButtons)
   {
      apple_input_rec_t *next = tmpButtons->next;

      tmpButtons->id          = tmp->id;
      tmpButtons->next        = NULL;
      tmp->next               = tmpButtons;

      tmp                     = tmp->next;
      tmpButtons              = next;
   }


   iohidmanager_hid_device_add_autodetect(adapter->slot,
         adapter->name, iohidmanager_hid.ident, dev_vid, dev_pid);

   return;

error:
   {
      apple_input_rec_t *tmp = NULL;
      while(adapter->hats != NULL)
      {
         tmp           = adapter->hats;
         adapter->hats = adapter->hats->next;
         free(tmp);
      }
      while(adapter->axes != NULL)
      {
         tmp           = adapter->axes;
         adapter->axes = adapter->axes->next;
         free(tmp);
      }
      while(adapter->buttons != NULL)
      {
         tmp              = adapter->buttons;
         adapter->buttons = adapter->buttons->next;
         free(tmp);
      }
      while(tmpAxes != NULL)
      {
         tmp     = tmpAxes;
         tmpAxes = tmpAxes->next;
         free(tmp);
      }
      while(tmpButtons != NULL)
      {
         tmp        = tmpButtons;
         tmpButtons = tmpButtons->next;
         free(tmp);
      }
      free(adapter);
   }
}
示例#18
0
CFDataRef APCreateHashFromDictionary(CFDictionaryRef dict)
{
    __block CFErrorRef error = NULL;
    __block SecTransformRef hashFunction = NULL;
    
    void(^cleanup)(void) = ^(void) {
        if (error != NULL) {
            CFShow(error);
            CFRelease(error);
            error = NULL;
        }
        if (hashFunction != NULL) {
            CFRelease(hashFunction);
            hashFunction = NULL;
        }
    };
    
    
    // Get the number of elements
    CFIndex count = CFDictionaryGetCount(dict);
    
    // Load the keys and build up the key array
    CFMutableArrayRef keyArray = CFArrayCreateMutable(kCFAllocatorDefault, count, NULL);
    CFStringRef keys[count];
    CFDictionaryGetKeysAndValues(dict, (const void**)&keys, NULL);
    for (int idx = 0; idx < count; idx++)
    {
        // Skip the signature key
        if (CFStringCompare(keys[idx], CFSTR("Signature"), 0) == kCFCompareEqualTo) {
            continue;
        }
        CFArrayAppendValue(keyArray, keys[idx]);
    }
    
    // Sort the array
    int context = kCFCompareCaseInsensitive;
    CFArraySortValues(keyArray, CFRangeMake(0, count-1), (CFComparatorFunction)CFStringCompare, &context);
    
    
    // Build the data
    CFMutableDataRef dictData = CFDataCreateMutable(kCFAllocatorDefault, 0);
    int keyCount = CFArrayGetCount(keyArray);
    for (int keyIndex = 0; keyIndex < keyCount; keyIndex++)
    {
        CFStringRef key = CFArrayGetValueAtIndex(keyArray, keyIndex);
        CFStringRef value = CFDictionaryGetValue(dict, key);
        
        CFDataRef valueData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
                                                                   value,
                                                                   kCFStringEncodingUTF8,
                                                                   0);
        const UInt8 *valueBuffer = CFDataGetBytePtr(valueData);
        CFDataAppendBytes(dictData, valueBuffer, CFDataGetLength(valueData));
        CFRelease(valueData);
    }
    
    
    // Hash the data
    hashFunction = SecDigestTransformCreate(kSecDigestSHA1, 0, &error);
    if (error != NULL) {
        CFRelease(dictData);
        cleanup();
        return NULL;
    }
    
    SecTransformSetAttribute(hashFunction,
                             kSecTransformInputAttributeName,
                             dictData,
                             &error);
    CFDataRef hashData = SecTransformExecute(hashFunction, &error);
    CFRelease(dictData);
    
    if (error != NULL) {
        cleanup();
        if (hashData) {
            CFRelease(hashData);
        }
        return NULL;
    }
    
    cleanup();
    
    return hashData;
}
CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData)
{
    CFErrorRef error = 0;
    CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0;
    RetainPtr<CFMutableDictionaryRef> propertyList = adoptCF((CFMutableDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorDefault, webArchiveData, kCFPropertyListMutableContainersAndLeaves, &format, &error));

    if (!propertyList) {
        if (error)
            return CFErrorCopyDescription(error);
        return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting data to property list.")));
    }

    RetainPtr<CFMutableArrayRef> resources = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
    CFArrayAppendValue(resources.get(), propertyList.get());

    while (CFArrayGetCount(resources.get())) {
        RetainPtr<CFMutableDictionaryRef> resourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(resources.get(), 0);
        CFArrayRemoveValueAtIndex(resources.get(), 0);

        CFMutableDictionaryRef mainResource = (CFMutableDictionaryRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebMainResource"));
        normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(mainResource, CFSTR("WebResourceURL")));
        convertWebResourceDataToString(mainResource);

        // Add subframeArchives to list for processing
        CFMutableArrayRef subframeArchives = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubframeArchives")); // WebSubframeArchivesKey in WebArchive.m
        if (subframeArchives)
            CFArrayAppendArray(resources.get(), subframeArchives, CFRangeMake(0, CFArrayGetCount(subframeArchives)));

        CFMutableArrayRef subresources = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubresources")); // WebSubresourcesKey in WebArchive.m
        if (!subresources)
            continue;

        CFIndex subresourcesCount = CFArrayGetCount(subresources);
        for (CFIndex i = 0; i < subresourcesCount; ++i) {
            CFMutableDictionaryRef subresourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(subresources, i);
            normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(subresourcePropertyList, CFSTR("WebResourceURL")));
            convertWebResourceResponseToDictionary(subresourcePropertyList);
            convertWebResourceDataToString(subresourcePropertyList);
        }

        // Sort the subresources so they're always in a predictable order for the dump
        CFArraySortValues(subresources, CFRangeMake(0, CFArrayGetCount(subresources)), compareResourceURLs, 0);
    }

    error = 0;

    RetainPtr<CFDataRef> xmlData = adoptCF(CFPropertyListCreateData(kCFAllocatorDefault, propertyList.get(), kCFPropertyListXMLFormat_v1_0, 0, &error));

    if (!xmlData) {
        if (error)
            return CFErrorCopyDescription(error);
        return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting property list to data.")));
    }

    RetainPtr<CFStringRef> xmlString = adoptCF(CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, xmlData.get(), kCFStringEncodingUTF8));
    RetainPtr<CFMutableStringRef> string = adoptCF(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, xmlString.get()));

    // Replace "Apple Computer" with "Apple" in the DTD declaration.
    CFStringFindAndReplace(string.get(), CFSTR("-//Apple Computer//"), CFSTR("-//Apple//"), CFRangeMake(0, CFStringGetLength(string.get())), 0);

    return string.leakRef();
}
示例#20
0
static boolean_t
updateConfiguration(int *newState)
{
	boolean_t		changed			= FALSE;
	CFStringRef		computerName;
	CFStringEncoding	computerNameEncoding;
	CFArrayRef		configuredServices	= NULL;
	CFDictionaryRef		dict;
	CFIndex			i;
	CFIndex			ifCount			= 0;
	CFMutableArrayRef	info			= NULL;
	CFArrayRef		interfaces		= NULL;
	CFStringRef		key;
	CFArrayRef		keys;
	CFIndex			n;
	CFMutableArrayRef	newConfigFile;
	CFMutableDictionaryRef	newDefaults;
	CFMutableDictionaryRef	newDict;
	CFMutableDictionaryRef	newGlobals;
	CFMutableDictionaryRef	newGlobalsX;			/* newGlobals without ServiceID */
	CFMutableDictionaryRef	newStartup;
	CFMutableDictionaryRef	newZones;
	CFNumberRef		num;
	CFMutableDictionaryRef	curGlobalsX;			/* curGlobals without ServiceID */
	CFStringRef		pattern;
	boolean_t		postGlobals		= FALSE;
	CFStringRef		primaryPort		= NULL;	/* primary interface */
	CFStringRef		primaryZone		= NULL;
	CFArrayRef		serviceOrder		= NULL;
	CFDictionaryRef		setGlobals		= NULL;

	cache_open();

	/*
	 * establish the "new" AppleTalk configuration
	 */
	*newState     = curState;
	newConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	newGlobals    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newDefaults   = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newStartup    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newZones      = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);

	/* initialize overall state */
	CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-NO-"));

	/*
	 * get the global settings (ServiceOrder, ComputerName, ...)
	 */
	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainSetup,
							 kSCEntNetAppleTalk);
	setGlobals = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (setGlobals) {
		if (isA_CFDictionary(setGlobals)) {
			/* get service order */
			serviceOrder = CFDictionaryGetValue(setGlobals,
							    kSCPropNetServiceOrder);
			serviceOrder = isA_CFArray(serviceOrder);
			if (serviceOrder) {
				CFRetain(serviceOrder);
			}
		} else {
			CFRelease(setGlobals);
			setGlobals = NULL;
		}
	}

	/*
	 * if we don't have an AppleTalk ServiceOrder, use IPv4's (if defined)
	 */
	if (!serviceOrder) {
		key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
								 kSCDynamicStoreDomainSetup,
								 kSCEntNetIPv4);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			if (isA_CFDictionary(dict)) {
				serviceOrder = CFDictionaryGetValue(dict,
								    kSCPropNetServiceOrder);
				serviceOrder = isA_CFArray(serviceOrder);
				if (serviceOrder) {
					CFRetain(serviceOrder);
				}
			}
			CFRelease(dict);
		}
	}

	/*
	 * get the list of ALL configured services
	 */
	configuredServices = entity_all(store, kSCEntNetAppleTalk, serviceOrder);
	if (configuredServices) {
		ifCount = CFArrayGetCount(configuredServices);
	}

	if (serviceOrder)	CFRelease(serviceOrder);

	/*
	 * get the list of ALL active interfaces
	 */
	key  = SCDynamicStoreKeyCreateNetworkInterface(NULL, kSCDynamicStoreDomainState);
	dict = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (dict) {
		if (isA_CFDictionary(dict)) {
			interfaces = CFDictionaryGetValue(dict,
							  kSCDynamicStorePropNetInterfaces);
			interfaces = isA_CFArray(interfaces);
			if (interfaces) {
				CFRetain(interfaces);
			}
		}
		CFRelease(dict);
	}

	/*
	 * get the list of previously configured services
	 */
	pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
							      kSCDynamicStoreDomainState,
							      kSCCompAnyRegex,
							      kSCEntNetAppleTalk);
	keys = SCDynamicStoreCopyKeyList(store, pattern);
	CFRelease(pattern);
	if (keys) {
		info = CFArrayCreateMutableCopy(NULL, 0, keys);
		CFRelease(keys);
	}

	/*
	 * iterate over each configured service to establish the new
	 * configuration.
	 */
	for (i = 0; i < ifCount; i++) {
		CFDictionaryRef		service;
		CFStringRef		ifName;
		CFStringRef		configMethod;
		CFMutableStringRef	portConfig	= NULL;
		CFArrayRef		networkRange;	/* for seed ports, CFArray[2] of CFNumber (lo, hi) */
		int			sNetwork;
		int			eNetwork;
		CFArrayRef		zoneList;	/* for seed ports, CFArray[] of CFString (zones names) */
		CFIndex			zCount;
		CFIndex			j;
		CFMutableDictionaryRef	ifDefaults	= NULL;
		CFNumberRef		defaultNetwork;
		CFNumberRef		defaultNode;
		CFStringRef		defaultZone;

		/* get AppleTalk service dictionary */
		service = CFArrayGetValueAtIndex(configuredServices, i);

		/* get interface name */
		ifName  = CFDictionaryGetValue(service, kSCPropNetInterfaceDeviceName);

		/* check inteface availability */
		if (!interfaces ||
		    !CFArrayContainsValue(interfaces, CFRangeMake(0, CFArrayGetCount(interfaces)), ifName)) {
			/* if interface not available */
			goto nextIF;
		}

		/* check interface link status */
		key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
								    kSCDynamicStoreDomainState,
								    ifName,
								    kSCEntNetLink);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			Boolean	linkStatus	= TRUE;  /* assume the link is "up" */
			Boolean	ifDetaching	= FALSE; /* assume link is not detaching */

			/* the link key for this interface is available */
			if (isA_CFDictionary(dict)) {
				CFBooleanRef	bVal;

				bVal = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
				if (isA_CFBoolean(bVal)) {
					linkStatus = CFBooleanGetValue(bVal);
				}

				/* check if interface is detaching - value
				   doesn't really matter, only that it exists */
				ifDetaching = CFDictionaryContainsKey(dict, kSCPropNetLinkDetaching);
			}
			CFRelease(dict);

			if (!linkStatus || ifDetaching) {
				/* if link status down or the interface is detaching */
				goto nextIF;
			}
		}

		/*
		 * Determine configuration method for this service
		 */
		configMethod = CFDictionaryGetValue(service, kSCPropNetAppleTalkConfigMethod);
		if (!isA_CFString(configMethod)) {
			/* if no ConfigMethod */
			goto nextIF;
		}

		if (!CFEqual(configMethod, kSCValNetAppleTalkConfigMethodNode      ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter    ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not one of the expected values, disable */
			SCLog(TRUE, LOG_NOTICE,
			      CFSTR("Unexpected AppleTalk ConfigMethod: %@"),
			      configMethod);
			goto nextIF;
		}

		/*
		 * the first service to be defined will always be "primary"
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFDictionaryRef	active;

			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryService,
					     CFDictionaryGetValue(service, CFSTR("ServiceID")));
			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryInterface,
					     ifName);

			/* and check if AT newtorking is active on the primary interface */
			key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
									    kSCDynamicStoreDomainState,
									    ifName,
									    kSCEntNetAppleTalk);
			active = cache_SCDynamicStoreCopyValue(store, key);
			CFRelease(key);
			if (active) {
				if (isA_CFDictionary(active)) {
					postGlobals = TRUE;
				}
				CFRelease(active);
			}
		}

		/*
		 * define the port
		 */
		portConfig = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(portConfig, NULL, CFSTR("%@:"), ifName);

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			CFNumberRef	num;

			/*
			 * we have been asked to configure this interface as a
			 * seed port. Ensure that we have been provided at least
			 * one network number, have been provided with at least
			 * one zonename, ...
			 */

			networkRange = CFDictionaryGetValue(service,
							    kSCPropNetAppleTalkSeedNetworkRange);
			if (!isA_CFArray(networkRange) || (CFArrayGetCount(networkRange) == 0)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}

			/*
			 * establish the starting and ending network numbers
			 */
			num = CFArrayGetValueAtIndex(networkRange, 0);
			if (!isA_CFNumber(num)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}
			CFNumberGetValue(num, kCFNumberIntType, &sNetwork);
			eNetwork = sNetwork;

			if (CFArrayGetCount(networkRange) > 1) {
				num = CFArrayGetValueAtIndex(networkRange, 1);
				if (!isA_CFNumber(num)) {
					SCLog(TRUE, LOG_NOTICE,
					      CFSTR("AppleTalk configuration error (%@)"),
					      kSCPropNetAppleTalkSeedNetworkRange);
					goto nextIF;
				}
				CFNumberGetValue(num, kCFNumberIntType, &eNetwork);
			}
			CFStringAppendFormat(portConfig, NULL, CFSTR("%d:%d:"), sNetwork, eNetwork);

			/*
			 * establish the zones associated with this port
			 */
			zoneList = CFDictionaryGetValue(service,
							kSCPropNetAppleTalkSeedZones);
			if (!isA_CFArray(zoneList)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}

			zCount = CFArrayGetCount(zoneList);
			for (j = 0; j < zCount; j++) {
				CFStringRef		zone;
				CFArrayRef		ifList;
				CFMutableArrayRef	newIFList;

				zone = CFArrayGetValueAtIndex(zoneList, j);
				if (!isA_CFString(zone)) {
					continue;
				}

				if (CFDictionaryGetValueIfPresent(newZones, zone, (const void **)&ifList)) {
					/* known zone */
					newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
				} else {
					/* new zone */
					newIFList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
				}
				CFArrayAppendValue(newIFList, ifName);
				CFArraySortValues(newIFList,
						  CFRangeMake(0, CFArrayGetCount(newIFList)),
						  (CFComparatorFunction)CFStringCompare,
						  NULL);
				CFDictionarySetValue(newZones, zone, newIFList);
				CFRelease(newIFList);

				/*
				 * flag the default zone
				 */
				if (!primaryZone) {
					primaryZone = CFRetain(zone);
				}
			}
			if (!primaryZone) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}
		}

		/* get the (per-interface) "Computer Name" */
		computerName = CFDictionaryGetValue(service,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(service,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);

		/*
		 * declare the first configured AppleTalk service / interface
		 * as the "home port".
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFStringAppend(portConfig, CFSTR("*"));
			primaryPort = CFRetain(ifName);
		}
		CFArrayAppendValue(newConfigFile, portConfig);

		/*
		 * get the per-interface defaults
		 */
		ifDefaults = CFDictionaryCreateMutable(NULL,
						       0,
						       &kCFTypeDictionaryKeyCallBacks,
						       &kCFTypeDictionaryValueCallBacks);

		defaultNetwork = CFDictionaryGetValue(service, kSCPropNetAppleTalkNetworkID);
		defaultNode    = CFDictionaryGetValue(service, kSCPropNetAppleTalkNodeID);
		if (isA_CFNumber(defaultNetwork) && isA_CFNumber(defaultNode)) {
			/*
			 * set the default node and network
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNetworkID,
					     defaultNetwork);
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNodeID,
					     defaultNode);
		}

		if ((CFDictionaryGetValueIfPresent(service,
						   kSCPropNetAppleTalkDefaultZone,
						   (const void **)&defaultZone) == TRUE)) {
			/*
			 * set the default zone for this interface
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkDefaultZone,
					     defaultZone);
		}

		CFDictionarySetValue(newDefaults, ifName, ifDefaults);
		CFRelease(ifDefaults);

		switch (CFArrayGetCount(newConfigFile)) {
			case 1:
				/*
				 * first AppleTalk interface
				 */
				CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), ifName);
				break;
			case 2:
				/* second AppleTalk interface */
				if (!CFEqual(CFDictionaryGetValue(newStartup, CFSTR("APPLETALK")),
					     CFSTR("-ROUTER-"))) {
					/*
					 * if not routing (yet), configure as multi-home
					 */
					CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-MULTIHOME-"));
				}
				break;
		}

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter) ||
		    CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not a simple node, enable routing */
			CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-ROUTER-"));
		}

		/*
		 * establish the State:/Network/Service/nnn/AppleTalk key info
		 */
		key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
								  kSCDynamicStoreDomainState,
								  CFDictionaryGetValue(service, CFSTR("ServiceID")),
								  kSCEntNetAppleTalk);
		newDict = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
		CFDictionaryAddValue(newDict, kSCPropInterfaceName, ifName);
		cache_SCDynamicStoreSetValue(store, key, newDict);
		CFRelease(newDict);
		if (info) {
			j = CFArrayGetFirstIndexOfValue(info,
							CFRangeMake(0, CFArrayGetCount(info)),
							key);
			if (j != kCFNotFound) {
				CFArrayRemoveValueAtIndex(info, j);
			}
		}
		CFRelease(key);

	    nextIF :

		if (portConfig)	CFRelease(portConfig);
	}

	if (primaryZone) {
		CFArrayRef		ifList;
		CFMutableArrayRef	newIFList;

		ifList = CFDictionaryGetValue(newZones, primaryZone);
		if (CFArrayContainsValue(ifList,
					 CFRangeMake(0, CFArrayGetCount(ifList)),
					 primaryPort)) {
			newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
			CFArrayAppendValue(newIFList, CFSTR("*"));
			CFDictionarySetValue(newZones, primaryZone, newIFList);
			CFRelease(newIFList);
		}
		CFRelease(primaryZone);
	}
	if (primaryPort) {
		CFRelease(primaryPort);
	}

	/* sort the ports */
	i = CFArrayGetCount(newConfigFile);
	CFArraySortValues(newConfigFile,
			  CFRangeMake(0, i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* add the zones to the configuration */
	CFDictionaryApplyFunction(newZones, addZoneToPorts, newConfigFile);
	CFRelease(newZones);

	/* sort the zones */
	CFArraySortValues(newConfigFile,
			  CFRangeMake(i, CFArrayGetCount(newConfigFile)-i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* ensure that the last line of the configuration file is terminated */
	CFArrayAppendValue(newConfigFile, CFSTR(""));

	/*
	 * Check if we have a "ComputerName" and look elsewhere if we don't have
	 * one yet.
	 */
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME")) &&
	    (setGlobals != NULL)) {
		computerName = CFDictionaryGetValue(setGlobals,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(setGlobals,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		computerName = SCDynamicStoreCopyComputerName(store, &computerNameEncoding);
		if (computerName) {
			encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
			CFRelease(computerName);
		}
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		struct utsname	name;

		if (uname(&name) == 0) {
			computerName = CFStringCreateWithCString(NULL, name.nodename, kCFStringEncodingASCII);
			if (computerName) {
				encodeName(computerName, kCFStringEncodingASCII, NULL, newGlobals);
				CFRelease(computerName);
			}
		}
	}

	/* compare the previous and current configurations */

	curGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, curGlobals);
	CFDictionaryRemoveValue(curGlobalsX, kSCDynamicStorePropNetPrimaryService);

	newGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, newGlobals);
	CFDictionaryRemoveValue(newGlobalsX, kSCDynamicStorePropNetPrimaryService);

	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainState,
							 kSCEntNetAppleTalk);

	if (CFEqual(curGlobalsX   , newGlobalsX   ) &&
	    CFEqual(curConfigFile , newConfigFile) &&
	    CFEqual(curDefaults   , newDefaults  ) &&
	    CFEqual(curStartup    , newStartup   )
	    ) {
		/*
		 * the configuration has not changed.
		 */

		if (postGlobals) {
			/*
			 * the requested configuration hasn't changed but we
			 * now need to tell everyone that AppleTalk is active.
			 */
			if (!SCDynamicStoreSetValue(store, key, newGlobals)) {
				SCLog(TRUE,
				      LOG_ERR,
				      CFSTR("SCDynamicStoreSetValue() failed: %s"),
				      SCErrorString(SCError()));
			}
		}

		CFRelease(newGlobals);
		CFRelease(newConfigFile);
		CFRelease(newDefaults);
		CFRelease(newStartup);
	} else if (CFArrayGetCount(newConfigFile) <= 1) {
		/*
		 * the configuration has changed but there are no
		 * longer any interfaces configured for AppleTalk
		 * networking.
		 */

		/*
		 * remove the global (State:/Network/Global/AppleTalk) key.
		 *
		 * Note: it will be restored later after AT networking has
		 *       been activated.
		 */

		/* remove the (/etc/appletalk.cfg) configuration file */
		(void)unlink(AT_CFG_FILE);

		/*
		 * update the per-service (and global) state
		 */
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = -(abs(curState) + 1);
		changed = TRUE;
	} else {
		/*
		 * the configuration has changed.
		 */

		/* update the (/etc/appletalk.cfg) configuration file */
		configWrite(AT_CFG_FILE, newConfigFile);

		/*
		 * update the per-service (and global) state
		 *
		 * Note: if present, we remove any existing global state key and allow it
		 *       to be restored after the stack has been re-started.
		 */
		CFDictionaryApplyFunction(newDefaults, updateDefaults, NULL);
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = abs(curState) + 1;
		changed = TRUE;
	}

	CFRelease(curGlobalsX);
	CFRelease(newGlobalsX);
	CFRelease(key);

	if (changed) {
		CFRelease(curGlobals);
		curGlobals    = newGlobals;
		CFRelease(curConfigFile);
		curConfigFile = newConfigFile;
		CFRelease(curDefaults);
		curDefaults   = newDefaults;
		CFRelease(curStartup);
		curStartup    = newStartup;
	}

	if (info)		CFRelease(info);
	if (interfaces)		CFRelease(interfaces);
	if (configuredServices)	CFRelease(configuredServices);
	if (setGlobals)		CFRelease(setGlobals);

	cache_close();

	return changed;
}
__private_extern__
CF_RETURNS_RETAINED CFDictionaryRef
proxy_configuration_update(CFDictionaryRef	defaultProxy,
			   CFDictionaryRef	services,
			   CFArrayRef		serviceOrder,
			   CFDictionaryRef	servicesInfo)
{
	CFIndex			i;
	CFMutableDictionaryRef	myDefault;
	Boolean			myOrderAdded	= FALSE;
	CFMutableDictionaryRef	newProxy	= NULL;
	CFIndex			n_proxies;
	CFDictionaryRef		proxy;
	CFMutableArrayRef	proxies;

	// establish full list of proxies

	proxies = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	// collect (and add) any "supplemental" proxy configurations

	add_supplemental_proxies(proxies, services, serviceOrder);

	// add the "default" proxy

	add_default_proxy(proxies, defaultProxy, &myOrderAdded);

	// sort proxies, cleanup

	n_proxies = CFArrayGetCount(proxies);
	if (n_proxies > 1) {
		CFArraySortValues(proxies, CFRangeMake(0, n_proxies), compareDomain, NULL);
	}

	// cleanup

	for (i = n_proxies - 1; i >= 0; i--) {
		proxy = CFArrayGetValueAtIndex(proxies, i);

		if ((i > 0) &&
		    !CFDictionaryContainsKey(proxy, kSCPropNetProxiesSupplementalMatchDomain)) {
			// remove non-supplemental proxy
			CFArrayRemoveValueAtIndex(proxies, i);
			n_proxies--;
			continue;
		}

		newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
		CFDictionaryRemoveValue(newProxy, PROXY_MATCH_ORDER_KEY);
		CFDictionaryRemoveValue(newProxy, ORDER_KEY);
		CFArraySetValueAtIndex(proxies, i, newProxy);
		CFRelease(newProxy);
	}

	// update the default proxy

	myDefault = CFDictionaryCreateMutableCopy(NULL,
						  0,
						  CFArrayGetValueAtIndex(proxies, 0));
	if (myOrderAdded && (n_proxies > 1)) {
		CFDictionaryRef	proxy;

		proxy = CFArrayGetValueAtIndex(proxies, 1);
		if (CFDictionaryContainsKey(proxy, kSCPropNetProxiesSupplementalMatchDomain)) {
			// if not a supplemental "default" proxy (a match domain name is
			// present)
			CFDictionaryRemoveValue(myDefault, PROXY_MATCH_ORDER_KEY);
		}
	}
	CFArraySetValueAtIndex(proxies, 0, myDefault);
	CFRelease(myDefault);

	// establish proxy configuration

	if (n_proxies > 0) {
		CFDictionaryRef		app_layer;
		CFDictionaryRef		scoped;
		CFArrayRef		serviceOrderAll;
		Boolean			skip		= FALSE;
		CFArrayRef		supplemental;

		proxy = CFArrayGetValueAtIndex(proxies, 0);
		if (!CFDictionaryContainsKey(proxy, kSCPropNetProxiesSupplementalMatchDomain)) {
			// if we have "a" default (non-supplemental) proxy
			newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
			CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchDomains);
			CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchOrders);
			skip = TRUE;
		} else {
			newProxy = CFDictionaryCreateMutable(NULL,
							     0,
							     &kCFTypeDictionaryKeyCallBacks,
							     &kCFTypeDictionaryValueCallBacks);
		}

		serviceOrderAll = service_order_copy_all(services, serviceOrder);

		// collect (and add) any "supplemental" proxy configurations

		supplemental = copy_supplemental_proxies(proxies, skip);
		if (supplemental != NULL) {
			CFDictionarySetValue(newProxy, kSCPropNetProxiesSupplemental, supplemental);
			CFRelease(supplemental);
		}

		// collect (and add) any "scoped" proxy configurations

		scoped = copy_scoped_proxies(services, serviceOrderAll);
		if (scoped != NULL) {
			CFDictionarySetValue(newProxy, kSCPropNetProxiesScoped, scoped);
			CFRelease(scoped);
		}

		// collect (and add) any "services" based proxy configurations

		app_layer = copy_app_layer_vpn_proxies(services, serviceOrderAll, servicesInfo);
		if (app_layer != NULL) {
			CFDictionarySetValue(newProxy, kSCPropNetProxiesServices, app_layer);
			CFRelease(app_layer);
		}

		if (serviceOrderAll != NULL) {
			CFRelease(serviceOrderAll);
		}
	} else {
		newProxy = NULL;
	}

	CFRelease(proxies);
	return newProxy;
}
void printKextInfo(CFDictionaryRef kextInfo, KextstatArgs * toolArgs)
{
    CFBooleanRef      isKernelComponent      = NULL;  // do not release
    CFNumberRef       loadTag                = NULL;  // do not release
    CFNumberRef       retainCount            = NULL;  // do not release
    CFNumberRef       loadAddress            = NULL;  // do not release
    CFNumberRef       loadSize               = NULL;  // do not release
    CFNumberRef       wiredSize              = NULL;  // do not release
    CFStringRef       bundleID               = NULL;  // do not release
    CFStringRef       bundleVersion          = NULL;  // do not release
    CFArrayRef        dependencyLoadTags     = NULL;  // do not release
    CFMutableArrayRef sortedLoadTags         = NULL;  // must release

    uint32_t          loadTagValue           = kOSKextInvalidLoadTag;
    uint32_t          retainCountValue       = (uint32_t)-1;
    uint64_t          loadAddressValue       = (uint64_t)-1;
    uint32_t          loadSizeValue          = (uint32_t)-1;
    uint32_t          wiredSizeValue         = (uint32_t)-1;
    uint32_t          cpuTypeValue           = (uint32_t)-1;
    uint32_t          cpuSubTypeValue        = (uint32_t)-1;
    char            * bundleIDCString        = NULL;  // must free
    char            * bundleVersionCString   = NULL;  // must free
    
    CFIndex           count, i;

    loadTag = (CFNumberRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleLoadTagKey));
    retainCount = (CFNumberRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleRetainCountKey));
    loadAddress = (CFNumberRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleLoadAddressKey));
    loadSize = (CFNumberRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleLoadSizeKey));
    wiredSize = (CFNumberRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleWiredSizeKey));
    bundleID = (CFStringRef)CFDictionaryGetValue(kextInfo,
        kCFBundleIdentifierKey);
    bundleVersion = (CFStringRef)CFDictionaryGetValue(kextInfo,
        kCFBundleVersionKey);
    dependencyLoadTags = (CFArrayRef)CFDictionaryGetValue(kextInfo,
        CFSTR(kOSBundleDependenciesKey));

   /* If the -k flag was given, skip any kernel components unless
    * they are explicitly requested.
    */
    if (toolArgs->flagNoKernelComponents) {
        isKernelComponent = (CFBooleanRef)CFDictionaryGetValue(kextInfo,
            CFSTR(kOSKernelResourceKey));
        if (isKernelComponent && CFBooleanGetValue(isKernelComponent)) {
            if (bundleID &&
                kCFNotFound == CFArrayGetFirstIndexOfValue(toolArgs->bundleIDs,
                    RANGE_ALL(toolArgs->bundleIDs), bundleID)) {

                goto finish;
            }
        }
    }

    if (!getNumValue(loadTag, kCFNumberSInt32Type, &loadTagValue)) {
        loadTagValue = kOSKextInvalidLoadTag;
    }

   /* Never print the info for the kernel (loadTag 0, id __kernel__).
    */
    if (loadTagValue == 0) {
        goto finish;
    }

    if (!getNumValue(retainCount, kCFNumberSInt32Type, &retainCountValue)) {
        retainCountValue = (uint32_t)-1;
    }
    if (!getNumValue(loadAddress, kCFNumberSInt64Type, &loadAddressValue)) {
        loadAddressValue = (uint64_t)-1;
    }
    if (!getNumValue(loadSize, kCFNumberSInt32Type, &loadSizeValue)) {
        loadSizeValue = (uint32_t)-1;
    }
    if (!getNumValue(wiredSize, kCFNumberSInt32Type, &wiredSizeValue)) {
        wiredSizeValue = (uint32_t)-1;
    }
    if (!getNumValue(((CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleCPUTypeKey))), kCFNumberSInt32Type, &cpuTypeValue)) {
        cpuTypeValue = (uint32_t)-1;
    }
    if (!getNumValue(((CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleCPUSubtypeKey))), kCFNumberSInt32Type, &cpuSubTypeValue)) {
        cpuSubTypeValue = (uint32_t)-1;
    }

    bundleIDCString = createUTF8CStringForCFString(bundleID);
    bundleVersionCString = createUTF8CStringForCFString(bundleVersion);

   /* First column has no leading space.
    *
    * These field widths are from the old kextstat, may want to change them.
    */
    if (loadTagValue == kOSKextInvalidLoadTag) {
        fprintf(stdout, "%5s", kStringInvalidShort);
    } else {
        fprintf(stdout, "%5d", loadTagValue);
    }

    if (retainCountValue == (uint32_t)-1) {
        fprintf(stdout, " %4s", kStringInvalidShort);
    } else {
        fprintf(stdout, " %4d", retainCountValue);
    }

    if (toolArgs->runningKernelArch->cputype & CPU_ARCH_ABI64) {
        if (loadAddressValue == (uint64_t)-1) {
            fprintf(stdout, " %-18s", kStringInvalidLong);
        } else {
            fprintf(stdout, " %#-18llx", (uint64_t)loadAddressValue);
        }
    } else {
        if (loadAddressValue == (uint64_t)-1) {
            fprintf(stdout, " %-10s", kStringInvalidLong);
        } else {
            fprintf(stdout, " %#-10x", (uint32_t)loadAddressValue);
        }
    }

    if (loadSizeValue == (uint32_t)-1) {
        fprintf(stdout, " %-10s", kStringInvalidLong);
    } else {
        fprintf(stdout, " %#-10x", loadSizeValue);
    }

    if (wiredSizeValue == (uint32_t)-1) {
        fprintf(stdout, " %-10s", kStringInvalidLong);
    } else {
        fprintf(stdout, " %#-10x", wiredSizeValue);
    }

    if (toolArgs->flagShowArchitecture) {
        // include kext cputype/cpusubtype info
        if (cpuTypeValue == (uint32_t) -1) {
            fprintf(stdout, " %10s/%-7s", kStringInvalidLong, kStringInvalidLong);
        }
        else {
            const NXArchInfo * archName = NXGetArchInfoFromCpuType(cpuTypeValue, cpuSubTypeValue);

            if (archName != NULL) {
                fprintf(stdout, " %-18s", archName->name);
            }
            else {
                fprintf(stdout, " %#010x/%#-7x", cpuTypeValue, cpuSubTypeValue);
            }
        }
    }

    fprintf(stdout, " %s",
        bundleIDCString ? bundleIDCString : kStringInvalidLong);
        
    fprintf(stdout, " (%s)",
        bundleVersionCString ? bundleVersionCString : kStringInvalidLong);

    if (dependencyLoadTags && CFArrayGetCount(dependencyLoadTags)) {
        sortedLoadTags = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0,
            dependencyLoadTags);
        if (!sortedLoadTags) {
            OSKextLogMemError();
            goto finish;
        }

        CFArraySortValues(sortedLoadTags, RANGE_ALL(sortedLoadTags),
            &compareNumbers, /* context */ NULL);
        
        fprintf(stdout, " <");
        count = CFArrayGetCount(sortedLoadTags);
        for (i = 0; i < count; i++) {
            loadTag = (CFNumberRef)CFArrayGetValueAtIndex(sortedLoadTags, i);
            if (!getNumValue(loadTag, kCFNumberSInt32Type, &loadTagValue)) {
                loadTagValue = kOSKextInvalidLoadTag;
            }

            if (loadTagValue == kOSKextInvalidLoadTag) {
                fprintf(stdout, "%s%s", i == 0 ? "" : " ", kStringInvalidShort);
            } else {
                fprintf(stdout, "%s%d", i == 0 ? "" : " ", loadTagValue);
            }

        }

        fprintf(stdout, ">");

    }
    
    fprintf(stdout, "\n");

finish:

    SAFE_RELEASE(sortedLoadTags);
    SAFE_FREE(bundleIDCString);
    SAFE_FREE(bundleVersionCString);
    return;
}