Beispiel #1
0
//_____________________________________________________________________________
//
bool	AUScope::RestoreElementNames (CFDictionaryRef& inNameDict)
{
	static char string[32];

	//first we have to see if we have enough elements and if not create them
	bool didAddElements = false;
	unsigned int maxElNum = 0;
	
	int dictSize = CFDictionaryGetCount(inNameDict);
	CFStringRef * keys = (CFStringRef*)CA_malloc (dictSize * sizeof (CFStringRef));
	CFDictionaryGetKeysAndValues (inNameDict, reinterpret_cast<const void**>(keys), NULL);
	for (int i = 0; i < dictSize; i++)
	{
		unsigned int intKey;
		CFStringGetCString (keys[i], string, 32, kCFStringEncodingASCII);
		sscanf (string, "%u", &intKey);
		if (UInt32(intKey) > maxElNum)
			maxElNum = intKey;
	}
	
	if (maxElNum >= GetNumberOfElements()) {
		SetNumberOfElements (maxElNum+1);
		didAddElements = true;
	}
		
		// OK, now we have the number of elements that we need - lets restate their names
	for (int i = 0; i < dictSize; i++)
	{
		CFStringRef elName = reinterpret_cast<CFStringRef>(CFDictionaryGetValue (inNameDict,  keys[i]));
		int intKey;
		CFStringGetCString (keys[i], string, 32, kCFStringEncodingASCII);
		sscanf (string, "%d", &intKey);
		GetElement (intKey)->SetName (elName);
	}
	free (keys);
	
	return didAddElements;
}
Beispiel #2
0
/**
 * checkForActivity checks to see if any items have completed since the last invokation.
 * If not, a message is displayed showing what item(s) are being waited on.
 **/
static void checkForActivity(CFRunLoopTimerRef aTimer, void* anInfo)
{
    static CFIndex aLastStatusDictionaryCount = -1;
    static CFStringRef aWaitingForString = NULL;
    
    StartupContext aStartupContext = (StartupContext)anInfo;

    if (aStartupContext && aStartupContext->aStatusDict)
      {
        CFIndex aCount = CFDictionaryGetCount(aStartupContext->aStatusDict);

        if (!aWaitingForString)
          {
            aWaitingForString = LocalizedString(aStartupContext->aResourcesBundlePath, kWaitingForKey);
          }
      
        if (aLastStatusDictionaryCount == aCount)
          {
            CFArrayRef aRunningList = StartupItemListGetRunning(aStartupContext->aWaitingList);
            if (aRunningList && CFArrayGetCount(aRunningList) > 0)
              {
                CFMutableDictionaryRef anItem = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(aRunningList, 0);
                CFStringRef anItemDescription = StartupItemGetDescription(anItem);
                CFStringRef aString = aWaitingForString && anItemDescription ? 
                                        CFStringCreateWithFormat(NULL, NULL, aWaitingForString, anItemDescription) : NULL;
                
                if (aString)
                  {
                    displayStatus(aStartupContext->aDisplayContext, aString);
                    CFRelease(aString);
                  }
                if (anItemDescription) CFRelease(anItemDescription);
              }
            if (aRunningList) CFRelease(aRunningList);
          }
        aLastStatusDictionaryCount = aCount;
      }
}
Beispiel #3
0
//---------------------------------------------------------------------------
// ProcessUPSEvent
//
//---------------------------------------------------------------------------
void ProcessUPSEvent(UPSDataRef upsDataRef, CFDictionaryRef event)
{
    UInt32		count, index;
    
    if ( !upsDataRef || !event)
        return;
      
    if ( (count = CFDictionaryGetCount(event)) )
    {	
        CFTypeRef * keys	= (CFTypeRef *) malloc(sizeof(CFTypeRef) * count);
        CFTypeRef * values	= (CFTypeRef *) malloc(sizeof(CFTypeRef) * count);

        CFDictionaryGetKeysAndValues(event, (const void **)keys, (const void **)values);
        
        for (index = 0; index < count; index++)
            CFDictionarySetValue(upsDataRef->upsStoreDict, keys[index], values[index]);
            
        free (keys);
        free (values);
            
        SCDynamicStoreSetValue(upsDataRef->upsStore, upsDataRef->upsStoreKey, upsDataRef->upsStoreDict);
    }
}
// quick message to indicate that the given domain has changed, and we should go through and invalidate any dictReps that involve this domain.
void _CFApplicationPreferencesDomainHasChanged(CFPreferencesDomainRef changedDomain) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if(__CFStandardUserPreferences) {  // only grovel over the prefs if there's something there to grovel
        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
        if(count < 32) {
            prefsArray = prefsBuf;
        } else {
            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
        }
        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);
        // For this operation, giving up the lock is the last thing we want to do, so use the modified flavor of _CFApplicationPreferencesContainsDomain
        for(idx = 0; idx < count; idx++) {
            _CFApplicationPreferences *appPrefs = prefsArray[idx];
            if(_CFApplicationPreferencesContainsDomainNoLock(appPrefs, changedDomain)) {
                updateDictRep(appPrefs);
            }
        }
        if(prefsArray != prefsBuf) _CFAllocatorDeallocateGC(alloc, prefsArray);
    }
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
void encode(ArgumentEncoder* encoder, CFDictionaryRef dictionary)
{
    CFIndex size = CFDictionaryGetCount(dictionary);
    Vector<CFTypeRef, 32> keys(size);
    Vector<CFTypeRef, 32> values(size);
    
    CFDictionaryGetKeysAndValues(dictionary, keys.data(), values.data());

    encoder->encodeUInt64(size);

    for (CFIndex i = 0; i < size; ++i) {
        ASSERT(keys[i]);
        ASSERT(CFGetTypeID(keys[i]) == CFStringGetTypeID());
        ASSERT(values[i]);

        // Ignore values we don't recognize.
        if (typeFromCFTypeRef(values[i]) == Unknown)
            continue;

        encode(encoder, static_cast<CFStringRef>(keys[i]));
        encode(encoder, values[i]);
    }
}
CFDictionaryRef SFB::Audio::AttachedPicture::CreateDictionaryRepresentation() const
{
	CFMutableDictionaryRef dictionaryRepresentation = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, mMetadata);

	CFIndex count = CFDictionaryGetCount(mChangedMetadata);

	CFTypeRef *keys = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count);
	CFTypeRef *values = (CFTypeRef *)malloc(sizeof(CFTypeRef) * (size_t)count);

	CFDictionaryGetKeysAndValues(mChangedMetadata, keys, values);

	for(CFIndex i = 0; i < count; ++i) {
		if(kCFNull == values[i])
			CFDictionaryRemoveValue(dictionaryRepresentation, keys[i]);
		else
			CFDictionarySetValue(dictionaryRepresentation, keys[i], values[i]);
	}

	free(keys), keys = nullptr;
	free(values), values = nullptr;

	return dictionaryRepresentation;
}
static void getVolatileKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *domain, void **buf[], CFIndex *numKeyValuePairs) {
    CFMutableDictionaryRef dict = (CFMutableDictionaryRef)domain;
    CFIndex count = CFDictionaryGetCount(dict);

    if (buf) {
        void **values;
        if ( count < *numKeyValuePairs ) {
            values = *buf + count;
            CFDictionaryGetKeysAndValues(dict, (const void **)*buf, (const void **)values);
        } else if (alloc != kCFAllocatorNull) {
            if (*buf) {
                *buf = (void **)CFAllocatorReallocate(alloc, *buf, count * 2 * sizeof(void *), 0);
            } else {
                *buf = (void **)CFAllocatorAllocate(alloc, count*2*sizeof(void *), 0);
            }
            if (*buf) {
                values = *buf + count;
                CFDictionaryGetKeysAndValues(dict, (const void **)*buf, (const void **)values);
            }
        }
    }
    *numKeyValuePairs = count;
}
void ResourceRequest::doUpdateResourceRequest()
{
    m_url = CFURLRequestGetURL(m_cfRequest.get());

    m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get());
    m_timeoutInterval = CFURLRequestGetTimeoutInterval(m_cfRequest.get());
    m_firstPartyForCookies = CFURLRequestGetMainDocumentURL(m_cfRequest.get());
    if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(m_cfRequest.get())) {
        m_httpMethod = method;
        CFRelease(method);
    }
    m_allowHTTPCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get());

    if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) {
        CFIndex headerCount = CFDictionaryGetCount(headers);
        Vector<const void*, 128> keys(headerCount);
        Vector<const void*, 128> values(headerCount);
        CFDictionaryGetKeysAndValues(headers, keys.data(), values.data());
        for (int i = 0; i < headerCount; ++i)
            m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
        CFRelease(headers);
    }

    m_responseContentDispositionEncodingFallbackArray.clear();
    RetainPtr<CFArrayRef> encodingFallbacks(AdoptCF, copyContentDispositionEncodingFallbackArray(m_cfRequest.get()));
    if (encodingFallbacks) {
        CFIndex count = CFArrayGetCount(encodingFallbacks.get());
        for (CFIndex i = 0; i < count; ++i) {
            CFStringEncoding encoding = reinterpret_cast<CFIndex>(CFArrayGetValueAtIndex(encodingFallbacks.get(), i));
            if (encoding != kCFStringEncodingInvalidId)
                m_responseContentDispositionEncodingFallbackArray.append(CFStringConvertEncodingToIANACharSetName(encoding));
        }
    }

    m_httpBody = httpBodyFromRequest(m_cfRequest.get());
}
Beispiel #9
0
/*! Creates a CFArray object containing CFString objects with portal group
 *  tags for a particular target.
 *  @param discoveryRec the discovery record.
 *  @param targetIQN the name of the target.
 *  @return an array of strings with portal group tags for the specified target. */
CFArrayRef iSCSIDiscoveryRecCreateArrayOfPortalGroupTags(iSCSIDiscoveryRecRef discoveryRec,
                                                         CFStringRef targetIQN)
{
    // Validate inputs
    if(!discoveryRec || !targetIQN)
        return NULL;
    
    // If target doesn't exist return NULL
    CFMutableDictionaryRef targetDict;
    if(!CFDictionaryGetValueIfPresent(discoveryRec,targetIQN,(void *)&targetDict))
        return NULL;
    
    // Otherwise get all keys, which correspond to the portal group tags
    const CFIndex count = CFDictionaryGetCount(targetDict);
    
    const void * keys[count];
    CFDictionaryGetKeysAndValues(targetDict,keys,NULL);
    
    CFArrayRef portalGroups = CFArrayCreate(kCFAllocatorDefault,
                                            keys,
                                            count,
                                            &kCFTypeArrayCallBacks);
    return portalGroups;
}
static void getXMLKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *xmlDomain, void **buf[], CFIndex *numKeyValuePairs) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFIndex count;
    __CFLock(&domain->_lock);
    if (!domain->_domainDict) {
        _loadXMLDomainIfStale((CFURLRef )context, domain);
    }
    count = CFDictionaryGetCount(domain->_domainDict);
    if (buf) {
        void **values;
        if (count <= *numKeyValuePairs) {
            values = *buf + count;
            CFDictionaryGetKeysAndValues(domain->_domainDict, (const void **)*buf, (const void **)values);
        } else if (alloc != kCFAllocatorNull) {
	    *buf = (void**) CFAllocatorReallocate(alloc, (*buf ? *buf : NULL), count * 2 * sizeof(void *), 0);
            if (*buf) {
                values = *buf + count;
                CFDictionaryGetKeysAndValues(domain->_domainDict, (const void **)*buf, (const void **)values);
            }
        }
    }
    *numKeyValuePairs = count;
    __CFUnlock(&domain->_lock);
}
Beispiel #11
0
/**
 * Loads the SystemStarter display bundle at the specified path.
 * A no-op if SystemStarter is not starting in graphical mode.
 **/
static void loadDisplayBundle (StartupContext aStartupContext, CFDictionaryRef anIPCMessage)
{
    if (!gVerboseFlag && anIPCMessage && aStartupContext)
      {
        CFStringRef aBundlePath = CFDictionaryGetValue(anIPCMessage, kIPCDisplayBundlePathKey);        
        if (aBundlePath && CFGetTypeID(aBundlePath) == CFStringGetTypeID())
          {
            extern void LoadDisplayPlugIn(CFStringRef);

            if (aStartupContext->aDisplayContext)
                freeDisplayContext(aStartupContext->aDisplayContext);
            LoadDisplayPlugIn(aBundlePath);
            aStartupContext->aDisplayContext = initDisplayContext();
            
              {
                CFStringRef aLocalizedString = LocalizedString(aStartupContext->aResourcesBundlePath, kWelcomeToMacintoshKey);
                if (aLocalizedString)
                  {
                    displayStatus(aStartupContext->aDisplayContext, aLocalizedString);
                    displayProgress(aStartupContext->aDisplayContext, ((float)CFDictionaryGetCount(aStartupContext->aStatusDict)/((float)aStartupContext->aServicesCount + 1.0)));
                    CFRelease(aLocalizedString);
                  }
              }
            
            if (gSafeBootFlag)
              {
                CFStringRef aLocalizedString = LocalizedString(aStartupContext->aResourcesBundlePath, kSafeBootKey);
                if (aLocalizedString)
                  {
                    (void) displaySafeBootMsg(aStartupContext->aDisplayContext, aLocalizedString);
                    CFRelease(aLocalizedString);
                  }
              }
          }
      }
}
void
debugCallback(
	CFNotificationCenterRef center,
	void *observer,
	CFStringRef name,
	const void *object,
	CFDictionaryRef userInfo)
{
	int i = 0;
	
	printf("Debug callback: %s\n", CFStringToCString(name));
	if (!userInfo)
		return;
	
	CFIndex count = CFDictionaryGetCount(userInfo);
	const void *keys[count];
	const void *values[count];
	CFDictionaryGetKeysAndValues(userInfo, keys, values);
	for(i = 0; i < count; i++)
	{
		printf("For i=%d, key: %s\n", i,
					CFStringToCString((CFStringRef)keys[i]));
	}
}
Beispiel #13
0
static void
ivar_dict_foreach(CFDictionaryRef dict, int (*func)(ANYARGS), VALUE farg)
{
    const long count = CFDictionaryGetCount(dict);
    if (count == 0) {
	return;
    }

    const void **keys = (const void **)malloc(sizeof(void *) * count);
    assert(keys != NULL);
    const void **values = (const void **)malloc(sizeof(void *) * count);
    assert(values != NULL);

    CFDictionaryGetKeysAndValues(dict, keys, values);

    for (long i = 0; i < count; i++) {
	if ((*func)(keys[i], values[i], farg) != ST_CONTINUE) {
	    break;
	}
    }

    free(keys);
    free(values);
}
Beispiel #14
0
static bool isSoftwareUpdateDevelopment(SecTrustRef trust) {
    bool isPolicy = false, isEKU = false;
    CFArrayRef policies = NULL;

    /* Policy used to evaluate was SWUpdateSigning */
    SecTrustCopyPolicies(trust, &policies);
    if (policies) {
        SecPolicyRef swUpdatePolicy = SecPolicyCreateAppleSWUpdateSigning();
        if (swUpdatePolicy && CFArrayContainsValue(policies, CFRangeMake(0, CFArrayGetCount(policies)),
                                                   swUpdatePolicy)) {
            isPolicy = true;
        }
        if (swUpdatePolicy) { CFRelease(swUpdatePolicy); }
        CFRelease(policies);
    }
    if (!isPolicy) {
        return false;
    }

    /* Only error was EKU on the leaf */
    CFArrayRef details = SecTrustCopyFilteredDetails(trust);
    CFIndex ix, count = CFArrayGetCount(details);
    bool hasDisqualifyingError = false;
    for (ix = 0; ix < count; ix++) {
        CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
        if (ix == 0) { // Leaf
            if (CFDictionaryGetCount(detail) != 1 || // One error
                CFDictionaryGetValue(detail, CFSTR("ExtendedKeyUsage")) != kCFBooleanFalse) { // kSecPolicyCheckExtendedKeyUsage
                hasDisqualifyingError = true;
                break;
            }
        } else {
            if (CFDictionaryGetCount(detail) > 0) { // No errors on other certs
                hasDisqualifyingError = true;
                break;
            }
        }
    }
    CFReleaseSafe(details);
    if (hasDisqualifyingError) {
        return false;
    }

    /* EKU on the leaf is the Apple Development Code Signing OID */
    SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
    CSSM_DATA *fieldValue = NULL;
    if (errSecSuccess != SecCertificateCopyFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, &fieldValue)) {
        return false;
    }
    if (fieldValue && fieldValue->Data && fieldValue->Length == sizeof(CSSM_X509_EXTENSION)) {
        const CSSM_X509_EXTENSION *ext = (const CSSM_X509_EXTENSION *)fieldValue->Data;
        if (ext->format == CSSM_X509_DATAFORMAT_PARSED) {
            const CE_ExtendedKeyUsage *ekus = (const CE_ExtendedKeyUsage *)ext->value.parsedValue;
            if (ekus && (ekus->numPurposes == 1) && ekus->purposes[0].Data &&
                (ekus->purposes[0].Length == CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Length) &&
                (memcmp(ekus->purposes[0].Data, CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Data,
                        ekus->purposes[0].Length) == 0)) {
                isEKU = true;
            }
        }
    }
    SecCertificateReleaseFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, fieldValue);
    return isEKU;
}
Beispiel #15
0
static void
dnssdUpdateDNSSDName(int from_callback)	/* I - Called from callback? */
{
  char		webif[1024];		/* Web interface share name */
#  ifdef __APPLE__
  SCDynamicStoreRef sc;			/* Context for dynamic store */
  CFDictionaryRef btmm;			/* Back-to-My-Mac domains */
  CFStringEncoding nameEncoding;	/* Encoding of computer name */
  CFStringRef	nameRef;		/* Host name CFString */
  char		nameBuffer[1024];	/* C-string buffer */
#  endif /* __APPLE__ */


 /*
  * Only share the web interface and printers when non-local listening is
  * enabled...
  */

  if (!DNSSDPort)
  {
   /*
    * Get the port we use for registrations.  If we are not listening on any
    * non-local ports, there is no sense sharing local printers via Bonjour...
    */

    cupsd_listener_t	*lis;		/* Current listening socket */

    for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
	 lis;
	 lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    {
      if (httpAddrLocalhost(&(lis->address)))
	continue;

      DNSSDPort = httpAddrPort(&(lis->address));
      break;
    }
  }

  if (!DNSSDPort)
    return;

 /*
  * Get the computer name as a c-string...
  */

#  ifdef __APPLE__
  sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);

  if (sc)
  {
   /*
    * Get the computer name from the dynamic store...
    */

    cupsdClearString(&DNSSDComputerName);

    if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
    {
      if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
			     kCFStringEncodingUTF8))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Dynamic store computer name is \"%s\".", nameBuffer);
	cupsdSetString(&DNSSDComputerName, nameBuffer);
      }

      CFRelease(nameRef);
    }

    if (!DNSSDComputerName)
    {
     /*
      * Use the ServerName instead...
      */

      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Using ServerName \"%s\" as computer name.", ServerName);
      cupsdSetString(&DNSSDComputerName, ServerName);
    }

   /*
    * Get the local hostname from the dynamic store...
    */

    cupsdClearString(&DNSSDHostName);

    if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
    {
      if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
			     kCFStringEncodingUTF8))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Dynamic store host name is \"%s\".", nameBuffer);
	cupsdSetString(&DNSSDHostName, nameBuffer);
      }

      CFRelease(nameRef);
    }

    if (!DNSSDHostName)
    {
     /*
      * Use the ServerName instead...
      */

      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Using ServerName \"%s\" as host name.", ServerName);
      cupsdSetString(&DNSSDHostName, ServerName);
    }

   /*
    * Get any Back-to-My-Mac domains and add them as aliases...
    */

    cupsdFreeAliases(DNSSDAlias);
    DNSSDAlias = NULL;

    btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
    if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
    {
      cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
		      (int)CFDictionaryGetCount(btmm));
      CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
    }
    else if (btmm)
      cupsdLogMessage(CUPSD_LOG_ERROR,
		      "Bad Back to My Mac data in dynamic store!");
    else
      cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");

    if (btmm)
      CFRelease(btmm);

    CFRelease(sc);
  }
  else
#  endif /* __APPLE__ */
#  ifdef HAVE_AVAHI
  if (DNSSDClient)
  {
    const char	*host_name = avahi_client_get_host_name(DNSSDClient);
    const char	*host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);

    cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);

    if (host_fqdn)
      cupsdSetString(&DNSSDHostName, host_fqdn);
    else if (strchr(ServerName, '.'))
      cupsdSetString(&DNSSDHostName, ServerName);
    else
      cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
  }
  else
#  endif /* HAVE_AVAHI */
  {
    cupsdSetString(&DNSSDComputerName, ServerName);

    if (strchr(ServerName, '.'))
      cupsdSetString(&DNSSDHostName, ServerName);
    else
      cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
  }

 /*
  * Then (re)register the web interface if enabled...
  */

  if (BrowseWebIF)
  {
    if (DNSSDComputerName)
      snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
    else
      strlcpy(webif, "CUPS", sizeof(webif));

    dnssdDeregisterInstance(&WebIFSrv, from_callback);
    dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer", DNSSDPort, NULL, 1, from_callback);
  }
}
Beispiel #16
0
static uint32_t
fsbundle_find_fssubtype(const char *bundle_path_C,
                        const char *claimed_name_C,
                        uint32_t    claimed_fssubtype)
{
    uint32_t result = FUSE_FSSUBTYPE_UNKNOWN;

    CFStringRef bundle_path_string  = NULL;
    CFStringRef claimed_name_string = NULL;

    CFURLRef    bundleURL = NULL;
    CFBundleRef bundleRef = NULL;

    CFDictionaryRef fspersonalities = NULL;

    CFIndex idx   = 0;
    CFIndex count = 0;
    Boolean found = false;

    CFStringRef     *keys     = NULL;
    CFDictionaryRef *subdicts = NULL;

    bundle_path_string = CFStringCreateWithCString(kCFAllocatorDefault,
                                                   bundle_path_C,
                                                   kCFStringEncodingUTF8);
    if (!bundle_path_string) {
        goto out;
    }

    bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
                                              bundle_path_string,
                                              kCFURLPOSIXPathStyle,
                                              true);
    if (!bundleURL) {
        goto out;
    }

    bundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
    if (!bundleRef) {
        goto out;
    }

    fspersonalities = CFBundleGetValueForInfoDictionaryKey(
                          bundleRef, CFSTR(kFSPersonalitiesKey));
    if (!fspersonalities) {
        goto out;
    }

    count = CFDictionaryGetCount(fspersonalities);
    if (count <= 0) {
        goto out;
    }

    keys = (CFStringRef *)malloc(count * sizeof(CFStringRef));
    subdicts = (CFDictionaryRef *)malloc(count * sizeof(CFDictionaryRef));

    if (!keys || !subdicts) {
        goto out;
    }

    CFDictionaryGetKeysAndValues(fspersonalities,
                                 (const void **)keys,
                                 (const void **)subdicts);

    if (claimed_fssubtype == (uint32_t)FUSE_FSSUBTYPE_INVALID) {
        goto lookupbyfsname;
    }

    for (idx = 0; idx < count; idx++) {
        CFNumberRef n = NULL;
        uint32_t candidate_fssubtype = (uint32_t)FUSE_FSSUBTYPE_INVALID;
        if (CFDictionaryGetValueIfPresent(subdicts[idx],
                                          (const void *)CFSTR(kFSSubTypeKey),
                                          (const void **)&n)) {
            if (CFNumberGetValue(n, kCFNumberIntType, &candidate_fssubtype)) {
                if (candidate_fssubtype == claimed_fssubtype) {
                    found = true;
                    result = candidate_fssubtype;
                    break;
                }
            }
        }
    }

    if (found) {
        goto out;
    }

lookupbyfsname:

    claimed_name_string = CFStringCreateWithCString(kCFAllocatorDefault,
                                                    claimed_name_C,
                                                    kCFStringEncodingUTF8);
    if (!claimed_name_string) {
        goto out;
    }

    for (idx = 0; idx < count; idx++) {
        CFRange where = CFStringFind(claimed_name_string, keys[idx],
                                     kCFCompareCaseInsensitive);
        if (where.location != kCFNotFound) {
            found = true;
        }
        if (found) {
            CFNumberRef n = NULL;
            uint32_t candidate_fssubtype = (uint32_t)FUSE_FSSUBTYPE_INVALID;
            if (CFDictionaryGetValueIfPresent(
                    subdicts[idx], (const void *)CFSTR(kFSSubTypeKey),
                    (const void **)&n)) {
                if (CFNumberGetValue(n, kCFNumberIntType,
                                     &candidate_fssubtype)) {
                    result = candidate_fssubtype;
                }
            }
            break;
        }
    }

out:
    if (keys) {
        free(keys);
    }

    if (subdicts) {
        free(subdicts);
    }

    if (bundle_path_string) {
        CFRelease(bundle_path_string);
    }

    if (bundleURL) {
        CFRelease(bundleURL);
    }

    if (claimed_name_string) {
        CFRelease(claimed_name_string);
    }

    if (bundleRef) {
        CFRelease(bundleRef);
    }

    return result;
}
__private_extern__ CFArrayRef  _CFPreferencesCreateDomainList(CFStringRef  userName, CFStringRef  hostName) {
    CFAllocatorRef prefAlloc = __CFPreferencesAllocator();
    CFArrayRef  domains;
    CFMutableArrayRef  marray;
    CFStringRef  *cachedDomainKeys;
    CFPreferencesDomainRef *cachedDomains;
    SInt32 idx, cnt;
    CFStringRef  suffix;
    UInt32 suffixLen;
    CFURLRef prefDir = _preferencesDirectoryForUserHost(userName, hostName);
    
    if (!prefDir) {
        return NULL;
    }
    if (hostName == kCFPreferencesAnyHost) {
        suffix = CFStringCreateWithCString(prefAlloc, ".plist", kCFStringEncodingASCII);
    } else if (hostName == kCFPreferencesCurrentHost) {
        CFStringRef hostID = _CFPreferencesGetByHostIdentifierString();
        suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostID);
    } else {
        suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostName);   // sketchy - this allows someone to create a domain list for an arbitrary hostname.
    }
    suffixLen = CFStringGetLength(suffix);
    
    domains = (CFArrayRef)CFURLCreatePropertyFromResource(prefAlloc, prefDir, kCFURLFileDirectoryContents, NULL);
    CFRelease(prefDir);
    if (domains){
        marray = CFArrayCreateMutableCopy(prefAlloc, 0, domains);
        CFRelease(domains);
    } else {
        marray = CFArrayCreateMutable(prefAlloc, 0, & kCFTypeArrayCallBacks);
    }
    for (idx = CFArrayGetCount(marray)-1; idx >= 0; idx --) {
        CFURLRef  url = (CFURLRef)CFArrayGetValueAtIndex(marray, idx);
        CFStringRef string = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
        if (!CFStringHasSuffix(string, suffix)) {
            CFArrayRemoveValueAtIndex(marray, idx);
        } else {
            CFStringRef  dom = CFStringCreateWithSubstring(prefAlloc, string, CFRangeMake(0, CFStringGetLength(string) - suffixLen));
            if (CFEqual(dom, CFSTR(".GlobalPreferences"))) {
                CFArraySetValueAtIndex(marray, idx, kCFPreferencesAnyApplication);
            } else {
                CFArraySetValueAtIndex(marray, idx, dom);
            }
            CFRelease(dom);
        }
        CFRelease(string);
    }
    CFRelease(suffix);
    
    // Now add any domains added in the cache; delete any that have been deleted in the cache
    __CFSpinLock(&domainCacheLock);
    if (!domainCache) {
        __CFSpinUnlock(&domainCacheLock);
        return marray;
    }
    cnt = CFDictionaryGetCount(domainCache);
    cachedDomainKeys = (CFStringRef *)CFAllocatorAllocate(prefAlloc, 2 * cnt * sizeof(CFStringRef), 0);
    cachedDomains = (CFPreferencesDomainRef *)(cachedDomainKeys + cnt);
    CFDictionaryGetKeysAndValues(domainCache, (const void **)cachedDomainKeys, (const void **)cachedDomains);
    __CFSpinUnlock(&domainCacheLock);
    suffix = _CFPreferencesCachePrefixForUserHost(userName, hostName);
    suffixLen = CFStringGetLength(suffix);
    
    for (idx = 0; idx < cnt; idx ++) {
        CFStringRef  domainKey = cachedDomainKeys[idx];
        CFPreferencesDomainRef domain = cachedDomains[idx];
        CFStringRef  domainName;
        CFIndex keyCount = 0;
        
        if (!CFStringHasPrefix(domainKey, suffix)) continue;
        domainName = CFStringCreateWithSubstring(prefAlloc, domainKey, CFRangeMake(suffixLen, CFStringGetLength(domainKey) - suffixLen));
        if (CFEqual(domainName, CFSTR("*"))) {
            CFRelease(domainName);
            domainName = (CFStringRef)CFRetain(kCFPreferencesAnyApplication);
        } else if (CFEqual(domainName, kCFPreferencesCurrentApplication)) {
            CFRelease(domainName);
            domainName = (CFStringRef)CFRetain(_CFProcessNameString());
        }
        CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain);
        keyCount = d ? CFDictionaryGetCount(d) : 0;
        if (keyCount) CFRelease(d);
        if (keyCount == 0) {
            // Domain was deleted
            SInt32 firstIndexOfValue = CFArrayGetFirstIndexOfValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName);
            if (0 <= firstIndexOfValue) {
                CFArrayRemoveValueAtIndex(marray, firstIndexOfValue);
            }
        } else if (!CFArrayContainsValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName)) {
            CFArrayAppendValue(marray, domainName);
        }
        CFRelease(domainName);
    }
    CFRelease(suffix);
    CFAllocatorDeallocate(prefAlloc, cachedDomainKeys);
    return marray;
}
static void
add_supplemental_proxies(CFMutableArrayRef proxies, CFDictionaryRef services, CFArrayRef service_order)
{
	const void *		keys_q[N_QUICK];
	const void **		keys	= keys_q;
	CFIndex			i;
	CFIndex			n_order;
	CFIndex			n_services;
	const void *		vals_q[N_QUICK];
	const void **		vals	= vals_q;

	n_services = isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0;
	if (n_services == 0) {
		return;		// if no services
	}

	if (n_services > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
		keys = CFAllocatorAllocate(NULL, n_services * sizeof(CFTypeRef), 0);
		vals = CFAllocatorAllocate(NULL, n_services * sizeof(CFTypeRef), 0);
	}

	n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;

	CFDictionaryGetKeysAndValues(services, keys, vals);
	for (i = 0; i < n_services; i++) {
		uint32_t		defaultOrder;
		CFDictionaryRef		proxy;
		CFMutableDictionaryRef	proxyWithDNS	= NULL;
		CFDictionaryRef		service		= (CFDictionaryRef)vals[i];

		if (!isA_CFDictionary(service)) {
			continue;
		}

		proxy = CFDictionaryGetValue(service, kSCEntNetProxies);
		if (!isA_CFDictionary(proxy)) {
			continue;
		}

		if ((G_supplemental_proxies_follow_dns != NULL) && CFBooleanGetValue(G_supplemental_proxies_follow_dns)) {
			CFDictionaryRef	dns;
			CFArrayRef	matchDomains;
			CFArrayRef	matchOrders;

			if (!CFDictionaryContainsKey(proxy, kSCPropNetProxiesSupplementalMatchDomains) &&
			    CFDictionaryGetValueIfPresent(service, kSCEntNetDNS, (const void **)&dns) &&
			    isA_CFDictionary(dns) &&
			    CFDictionaryGetValueIfPresent(dns, kSCPropNetDNSSupplementalMatchDomains, (const void **)&matchDomains) &&
			    isA_CFArray(matchDomains)) {
				proxyWithDNS = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
				CFDictionarySetValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchDomains, matchDomains);
				if (CFDictionaryGetValueIfPresent(dns, kSCPropNetDNSSupplementalMatchOrders, (const void **)&matchOrders) &&
				    isA_CFArray(matchOrders)) {
					CFDictionarySetValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchOrders, matchOrders);
				} else {
					CFDictionaryRemoveValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchOrders);
				}
				proxy = proxyWithDNS;
			}
		}

		defaultOrder = DEFAULT_MATCH_ORDER
			       - (DEFAULT_MATCH_ORDER / 2)
			       + ((DEFAULT_MATCH_ORDER / 1000) * i);
		if ((n_order > 0) &&
		    !CFArrayContainsValue(service_order, CFRangeMake(0, n_order), keys[i])) {
			// push out services not specified in service order
			defaultOrder += (DEFAULT_MATCH_ORDER / 1000) * n_services;
		}

		add_supplemental(proxies, proxy, defaultOrder);
		if (proxyWithDNS != NULL) CFRelease(proxyWithDNS);
	}

	if (keys != keys_q) {
		CFAllocatorDeallocate(NULL, keys);
		CFAllocatorDeallocate(NULL, vals);
	}

	return;
}
UInt32	CACFDictionary::Size () const
{
	return ToUInt32(CFDictionaryGetCount(mCFDictionary));
}
Beispiel #20
0
/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
OSStatus
SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
{
	/* bridge to support API functionality for legacy callers */
	OSStatus status = errSecSuccess;
	CFDataRef encodedExceptions = SecTrustCopyExceptions(trustRef);
	CFArrayRef exceptions = NULL,
            oldExceptions = SecTrustGetTrustExceptionsArray(trustRef);

	if (encodedExceptions) {
		exceptions = (CFArrayRef)CFPropertyListCreateWithData(kCFAllocatorDefault,
			encodedExceptions, kCFPropertyListImmutable, NULL, NULL);
		CFRelease(encodedExceptions);
		encodedExceptions = NULL;
	}

	if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
		CFRelease(exceptions);
		exceptions = NULL;
	}

	if (oldExceptions && exceptions &&
		CFArrayGetCount(oldExceptions) > CFArrayGetCount(exceptions)) {
		oldExceptions = NULL;
	}

	/* verify both exceptions are for the same leaf */
	if (oldExceptions && exceptions && CFArrayGetCount(oldExceptions) > 0) {
		CFDictionaryRef oldLeafExceptions = (CFDictionaryRef)CFArrayGetValueAtIndex(oldExceptions, 0);
		CFDictionaryRef leafExceptions = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, 0);
		CFDataRef oldDigest = (CFDataRef)CFDictionaryGetValue(oldLeafExceptions, CFSTR("SHA1Digest"));
		CFDataRef digest = (CFDataRef)CFDictionaryGetValue(leafExceptions, CFSTR("SHA1Digest"));
		if (!oldDigest || !digest || !CFEqual(oldDigest, digest)) {
			oldExceptions = NULL;
		}
	}

	/* add only those exceptions which are allowed by the supplied options */
	if (exceptions) {
		CFMutableArrayRef filteredExceptions = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
		CFIndex i, exceptionCount = (filteredExceptions) ? CFArrayGetCount(exceptions) : 0;

		for (i = 0; i < exceptionCount; ++i) {
			CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, i);
			CFDictionaryRef oldException = NULL;
			if (oldExceptions && i < CFArrayGetCount(oldExceptions)) {
				oldException = (CFDictionaryRef)CFArrayGetValueAtIndex(oldExceptions, i);
			}
			CFMutableDictionaryRef filteredException = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
																				 &kCFTypeDictionaryValueCallBacks);
			if (exception && filteredException) {
				SecExceptionFilterContext filterContext = { options, i, trustRef, filteredException, oldException };
				CFDictionaryApplyFunction(exception, filter_exception, &filterContext);
				CFArrayAppendValue(filteredExceptions, filteredException);
				CFRelease(filteredException);
			}
		}

		if (filteredExceptions) {
			CFIndex filteredCount = CFArrayGetCount(filteredExceptions);
			/* remove empty trailing entries to match iOS behavior */
			for (i = filteredCount; i-- > 1;) {
				CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(filteredExceptions, i);
				if (CFDictionaryGetCount(exception) == 0) {
					CFArrayRemoveValueAtIndex(filteredExceptions, i);
				} else {
					break;
				}
			}
			encodedExceptions = CFPropertyListCreateData(kCFAllocatorDefault,
				filteredExceptions, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
			CFRelease(filteredExceptions);

			SecTrustSetExceptions(trustRef, encodedExceptions);
			CFRelease(encodedExceptions);
		}
		CFRelease(exceptions);
	}

#if SECTRUST_DEPRECATION_WARNINGS
	bool displayModifyMsg = false;
	bool displayNetworkMsg = false;
	bool displayPolicyMsg = false;
	const char *baseMsg = "WARNING: SecTrustSetOptions called with";
	const char *modifyMsg = "Use SecTrustSetExceptions and SecTrustCopyExceptions to modify default trust results.";
	const char *networkMsg = "Use SecTrustSetNetworkFetchAllowed to specify whether missing certificates can be fetched from the network.";
	const char *policyMsg = "Use SecPolicyCreateRevocation to specify revocation policy requirements.";

	if (options & kSecTrustOptionAllowExpired) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionAllowExpired");
		displayModifyMsg = true;
	}
	if (options & kSecTrustOptionAllowExpiredRoot) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionAllowExpiredRoot");
		displayModifyMsg = true;
	}
	if (options & kSecTrustOptionFetchIssuerFromNet) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionFetchIssuerFromNet");
		displayNetworkMsg = true;
	}
	if (options & kSecTrustOptionRequireRevPerCert) {
		syslog(LOG_ERR, "%s %s.", baseMsg, "kSecTrustOptionRequireRevPerCert");
		displayPolicyMsg = true;
	}
	if (displayModifyMsg || displayNetworkMsg || displayPolicyMsg) {
		syslog(LOG_ERR, "%s %s %s",
			(displayModifyMsg) ? modifyMsg : "",
			(displayNetworkMsg) ? networkMsg : "",
			(displayPolicyMsg) ? policyMsg : "");
	}
#endif

	return status;
}
bool FLACMetadata::ReadMetadata(CFErrorRef *error)
{
	// Start from scratch
	CFDictionaryRemoveAllValues(mMetadata);
	CFDictionaryRemoveAllValues(mChangedMetadata);
	
	UInt8 buf [PATH_MAX];
	if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX))
		return false;
	
	FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();

	// ENOMEM sux
	if(NULL == chain)
		return false;
	
	if(!FLAC__metadata_chain_read(chain, reinterpret_cast<const char *>(buf))) {

		// Attempt to provide a descriptive error message
		if(NULL != error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			switch(FLAC__metadata_chain_status(chain)) {
				case FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);

					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
					
				case FLAC__METADATA_CHAIN_STATUS_BAD_METADATA:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file contains bad metadata."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
				default:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
			}
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataFileFormatNotRecognizedError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;
		}

		FLAC__metadata_chain_delete(chain), chain = NULL;
		
		return false;
	}
	
	FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new();

	if(NULL == iterator) {
		FLAC__metadata_chain_delete(chain), chain = NULL;		
		return false;
	}
	
	CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("FLAC"));

	FLAC__metadata_iterator_init(iterator, chain);
	
	FLAC__StreamMetadata *block = NULL;
	
	CFMutableDictionaryRef additionalMetadata = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																		  32,
																		  &kCFTypeDictionaryKeyCallBacks,
																		  &kCFTypeDictionaryValueCallBacks);
	
	do {
		block = FLAC__metadata_iterator_get_block(iterator);
		
		if(NULL == block)
			break;
		
		switch(block->type) {					
			case FLAC__METADATA_TYPE_VORBIS_COMMENT:				
				for(unsigned i = 0; i < block->data.vorbis_comment.num_comments; ++i) {
					
					char *fieldName = NULL;
					char *fieldValue = NULL;
					
					// Let FLAC parse the comment for us
					if(!FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(block->data.vorbis_comment.comments[i], &fieldName, &fieldValue)) {
						// Ignore malformed comments
						continue;
					}
					
					CFStringRef key = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault,
																	reinterpret_cast<const UInt8 *>(fieldName),
																	strlen(fieldName), 
																	kCFStringEncodingASCII,
																	false,
																	kCFAllocatorMalloc);

					CFStringRef value = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault,
																	  reinterpret_cast<const UInt8 *>(fieldValue),
																	  strlen(fieldValue), 
																	  kCFStringEncodingUTF8,
																	  false,
																	  kCFAllocatorMalloc);
					
					if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ALBUM"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataAlbumTitleKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ARTIST"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataArtistKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ALBUMARTIST"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataAlbumArtistKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("COMPOSER"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataComposerKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("GENRE"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataGenreKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DATE"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataReleaseDateKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DESCRIPTION"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataCommentKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TITLE"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataTitleKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TRACKNUMBER"), kCFCompareCaseInsensitive)) {
						int num = CFStringGetIntValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
						CFDictionarySetValue(mMetadata, kMetadataTrackNumberKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("TRACKTOTAL"), kCFCompareCaseInsensitive)) {
						int num = CFStringGetIntValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
						CFDictionarySetValue(mMetadata, kMetadataTrackTotalKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("COMPILATION"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataCompilationKey, CFStringGetIntValue(value) ? kCFBooleanTrue : kCFBooleanFalse);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DISCNUMBER"), kCFCompareCaseInsensitive)) {
						int num = CFStringGetIntValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
						CFDictionarySetValue(mMetadata, kMetadataDiscNumberKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("DISCTOTAL"), kCFCompareCaseInsensitive)) {
						int num = CFStringGetIntValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
						CFDictionarySetValue(mMetadata, kMetadataDiscTotalKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("ISRC"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataISRCKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("MCN"), kCFCompareCaseInsensitive))
						CFDictionarySetValue(mMetadata, kMetadataMCNKey, value);
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_REFERENCE_LOUDNESS"), kCFCompareCaseInsensitive)) {
						double num = CFStringGetDoubleValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num);
						CFDictionarySetValue(mMetadata, kReplayGainReferenceLoudnessKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_TRACK_GAIN"), kCFCompareCaseInsensitive)) {
						double num = CFStringGetDoubleValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num);
						CFDictionarySetValue(mMetadata, kReplayGainTrackGainKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_TRACK_PEAK"), kCFCompareCaseInsensitive)) {
						double num = CFStringGetDoubleValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num);
						CFDictionarySetValue(mMetadata, kReplayGainTrackPeakKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_ALBUM_GAIN"), kCFCompareCaseInsensitive)) {
						double num = CFStringGetDoubleValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num);
						CFDictionarySetValue(mMetadata, kReplayGainAlbumGainKey, number);
						CFRelease(number), number = NULL;
					}
					else if(kCFCompareEqualTo == CFStringCompare(key, CFSTR("REPLAYGAIN_ALBUM_PEAK"), kCFCompareCaseInsensitive)) {
						double num = CFStringGetDoubleValue(value);
						CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &num);
						CFDictionarySetValue(mMetadata, kReplayGainAlbumPeakKey, number);
						CFRelease(number), number = NULL;
					}
					// Put all unknown tags into the additional metadata
					else
						CFDictionarySetValue(additionalMetadata, key, value);
					
					CFRelease(key), key = NULL;
					CFRelease(value), value = NULL;
					
					fieldName = NULL;
					fieldValue = NULL;
				}
				break;
				
			case FLAC__METADATA_TYPE_PICTURE:
			{
				CFDataRef data = CFDataCreate(kCFAllocatorDefault, block->data.picture.data, block->data.picture.data_length);
				CFDictionarySetValue(mMetadata, kAlbumArtFrontCoverKey, data);
				CFRelease(data), data = NULL;
			}
			break;
				
			case FLAC__METADATA_TYPE_STREAMINFO:
			{
				CFNumberRef sampleRate = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.sample_rate);
				CFDictionarySetValue(mMetadata, kPropertiesSampleRateKey, sampleRate);
				CFRelease(sampleRate), sampleRate = NULL;

				CFNumberRef channelsPerFrame = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.channels);
				CFDictionarySetValue(mMetadata, kPropertiesChannelsPerFrameKey, channelsPerFrame);
				CFRelease(channelsPerFrame), channelsPerFrame = NULL;

				CFNumberRef bitsPerChannel = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &block->data.stream_info.bits_per_sample);
				CFDictionarySetValue(mMetadata, kPropertiesBitsPerChannelKey, bitsPerChannel);
				CFRelease(bitsPerChannel), bitsPerChannel = NULL;
				
				CFNumberRef totalFrames = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &block->data.stream_info.total_samples);
				CFDictionarySetValue(mMetadata, kPropertiesTotalFramesKey, totalFrames);
				CFRelease(totalFrames), totalFrames = NULL;

				double length = static_cast<double>(block->data.stream_info.total_samples / block->data.stream_info.sample_rate);
				CFNumberRef duration = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &length);
				CFDictionarySetValue(mMetadata, kPropertiesDurationKey, duration);
				CFRelease(duration), duration = NULL;

				double losslessBitrate = static_cast<double>(block->data.stream_info.sample_rate * block->data.stream_info.channels * block->data.stream_info.bits_per_sample) / 1000;
				CFNumberRef bitrate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &losslessBitrate);
				CFDictionarySetValue(mMetadata, kPropertiesBitrateKey, bitrate);
				CFRelease(bitrate), bitrate = NULL;
			}
			break;

			case FLAC__METADATA_TYPE_PADDING:						break;
			case FLAC__METADATA_TYPE_APPLICATION:					break;
			case FLAC__METADATA_TYPE_SEEKTABLE:						break;
			case FLAC__METADATA_TYPE_CUESHEET:						break;
			case FLAC__METADATA_TYPE_UNDEFINED:						break;

			default:												break;
		}
	} while(FLAC__metadata_iterator_next(iterator));

	if(CFDictionaryGetCount(additionalMetadata))
		SetAdditionalMetadata(additionalMetadata);
	
	CFRelease(additionalMetadata), additionalMetadata = NULL;
	
	FLAC__metadata_iterator_delete(iterator), iterator = NULL;
	FLAC__metadata_chain_delete(chain), chain = NULL;
	
	return true;
}
Beispiel #22
0
void InbandTextTrackPrivateAVF::processCueAttributes(CFAttributedStringRef attributedString, StringBuilder& content, StringBuilder& settings)
{
    // Some of the attributes we translate into per-cue WebVTT settings are are repeated on each part of an attributed string so only
    // process the first instance of each.
    enum AttributeFlags {
        Line = 1 << 0,
        Position = 1 << 1,
        Size = 1 << 2,
        Vertical = 1 << 3,
        Align = 1 << 4
    };
    unsigned processed = 0;

    String attributedStringValue = CFAttributedStringGetString(attributedString);
    CFIndex length = attributedStringValue.length();
    if (!length)
        return;

    CFRange effectiveRange = CFRangeMake(0, 0);
    while ((effectiveRange.location + effectiveRange.length) < length) {

        CFDictionaryRef attributes = CFAttributedStringGetAttributes(attributedString, effectiveRange.location + effectiveRange.length, &effectiveRange);
        if (!attributes)
            continue;

        StringBuilder tagStart;
        String tagEnd;
        CFIndex attributeCount = CFDictionaryGetCount(attributes);
        Vector<const void*> keys(attributeCount);
        Vector<const void*> values(attributeCount);
        CFDictionaryGetKeysAndValues(attributes, keys.data(), values.data());

        for (CFIndex i = 0; i < attributeCount; ++i) {
            CFStringRef key = static_cast<CFStringRef>(keys[i]);
            CFTypeRef value = values[i];
            if (CFGetTypeID(key) != CFStringGetTypeID() || !CFStringGetLength(key))
                continue;

            if (CFStringCompare(key, kCMTextMarkupAttribute_Alignment, 0) == kCFCompareEqualTo) {
                CFStringRef valueString = static_cast<CFStringRef>(value);
                if (CFGetTypeID(valueString) != CFStringGetTypeID() || !CFStringGetLength(valueString))
                    continue;
                if (processed & Align)
                    continue;
                processed |= Align;

                if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_Start, 0) == kCFCompareEqualTo)
                    settings.append("align:start ");
                else if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_Middle, 0) == kCFCompareEqualTo)
                    settings.append("align:middle ");
                else if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_End, 0) == kCFCompareEqualTo)
                    settings.append("align:end ");
                else
                    ASSERT_NOT_REACHED();

                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_BoldStyle, 0) == kCFCompareEqualTo) {
                if (static_cast<CFBooleanRef>(value) != kCFBooleanTrue)
                    continue;

                tagStart.append("<b>");
                tagEnd.insert("</b>", 0);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_ItalicStyle, 0) == kCFCompareEqualTo) {
                if (static_cast<CFBooleanRef>(value) != kCFBooleanTrue)
                    continue;

                tagStart.append("<i>");
                tagEnd.insert("</i>", 0);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_UnderlineStyle, 0) == kCFCompareEqualTo) {
                if (static_cast<CFBooleanRef>(value) != kCFBooleanTrue)
                    continue;

                tagStart.append("<u>");
                tagEnd.insert("</u>", 0);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_OrthogonalLinePositionPercentageRelativeToWritingDirection, 0) == kCFCompareEqualTo) {
                // Ignore the line position if the attributes also specify "size" so we keep WebVTT's default line logic
                if (CFDictionaryGetValue(attributes, kCMTextMarkupAttribute_WritingDirectionSizePercentage))
                    continue;
                if (CFGetTypeID(value) != CFNumberGetTypeID())
                    continue;
                if (processed & Line)
                    continue;
                processed |= Line;

                CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
                double position;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &position);
                settings.append(String::format("line:%ld%% ", lrint(position)));
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_TextPositionPercentageRelativeToWritingDirection, 0) == kCFCompareEqualTo) {
                if (CFGetTypeID(value) != CFNumberGetTypeID())
                    continue;
                if (processed & Position)
                    continue;
                processed |= Position;

                CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
                double position;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &position);
                settings.append(String::format("position:%ld%% ", lrint(position)));
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_WritingDirectionSizePercentage, 0) == kCFCompareEqualTo) {
                if (CFGetTypeID(value) != CFNumberGetTypeID())
                    continue;
                if (processed & Size)
                    continue;
                processed |= Size;

                CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
                double position;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &position);
                settings.append(String::format("size:%ld%% ", lrint(position)));
                continue;
            }
        }
        content.append(tagStart);
        content.append(attributedStringValue.substring(effectiveRange.location, effectiveRange.length));
        content.append(tagEnd);
    }
}
Beispiel #23
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;
}
// domain should already be locked.
static Boolean _writeXMLFile(CFURLRef url, CFMutableDictionaryRef dict, Boolean isWorldReadable, Boolean *tryAgain) {
    Boolean success = false;
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    *tryAgain = false;
    if (CFDictionaryGetCount(dict) == 0) {
        // Destroy the file
        CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL);
        if (val && CFBooleanGetValue(val)) {
            success = CFURLDestroyResource(url, NULL);
        } else {
            success = true;
        }
        if (val) CFRelease(val);
    } else {
        CFPropertyListFormat desiredFormat = __CFPreferencesShouldWriteXML() ? kCFPropertyListXMLFormat_v1_0 : kCFPropertyListBinaryFormat_v1_0;
        CFDataRef data = CFPropertyListCreateData(alloc, dict, desiredFormat, 0, NULL);
        if (data) {
            SInt32 mode;
#if TARGET_OS_OSX || TARGET_OS_LINUX
            mode = isWorldReadable ? S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH : S_IRUSR|S_IWUSR;
#else
	    mode = 0666;
#endif
#if TARGET_OS_OSX
            {	// Try quick atomic way first, then fallback to slower ways and error cases
                CFStringRef scheme = CFURLCopyScheme(url);
                if (!scheme) {
                    *tryAgain = false;
                    CFRelease(data);
                    return false;
                } else if (CFStringCompare(scheme, CFSTR("file"), 0) == kCFCompareEqualTo) {
                    SInt32 length = CFDataGetLength(data);
                    const void *bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(data);
                    Boolean atomicWriteSuccess = __CFWriteBytesToFileWithAtomicity(url, bytes, length, mode, true);
                    if (atomicWriteSuccess) {
                        CFRelease(scheme);
                        *tryAgain = false;
                        CFRelease(data);
                        return true;
                    }
                    if (!atomicWriteSuccess && thread_errno() == ENOSPC) {
                        CFRelease(scheme);
                        *tryAgain = false;
                        CFRelease(data);
                        return false;
                    }
                }
                CFRelease(scheme);
            }
#endif
            success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL);
            URLPropertyDictRelease();
            if (success) {
                CFDataRef readData;
                if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &readData, NULL, NULL, NULL) || !CFEqual(readData, data)) {
                    success = false;
                    *tryAgain = true;
                }
                if (readData) CFRelease(readData);
            } else {
                CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL);
                if (!val || !CFBooleanGetValue(val)) {
                    CFURLRef tmpURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("."), kCFURLPOSIXPathStyle, true, url); // Just "." because url is not a directory URL
                    CFURLRef parentURL = tmpURL ? CFURLCopyAbsoluteURL(tmpURL) : NULL;
                    if (tmpURL) CFRelease(tmpURL);
                    if (val) CFRelease(val);
                    val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, parentURL, kCFURLFileExists, NULL);
                    if ((!val || !CFBooleanGetValue(val)) && _createDirectory(parentURL, isWorldReadable)) {
                        // parent directory didn't exist; now it does; try again to write
                        success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL);
                        URLPropertyDictRelease();
                        if (success) {
                            CFDataRef rdData;
                            if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &rdData, NULL, NULL, NULL) || !CFEqual(rdData, data)) {
                                success = false;
                                *tryAgain = true;
                            }
                            if (rdData) CFRelease(rdData);
                        }
                        
                    }
                    if (parentURL) CFRelease(parentURL);
                }
                if (val) CFRelease(val);
            }
            CFRelease(data);
        } else {
            // ???  This should never happen
            CFLog(__kCFLogAssertion, CFSTR("Could not generate XML data for property list"));
            success = false;
        }
    }
    return success;
}
Beispiel #25
0
CFArrayRef /* of SCNetworkServiceRef's */
SCNetworkSetCopyServices(SCNetworkSetRef set)
{
	CFMutableArrayRef       array;
	CFDictionaryRef		dict;
	CFIndex			n;
	CFStringRef		path;
	SCNetworkSetPrivateRef	setPrivate	= (SCNetworkSetPrivateRef)set;

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

	path = SCPreferencesPathKeyCreateSetNetworkService(NULL, setPrivate->setID, NULL);
	dict = SCPreferencesPathGetValue(setPrivate->prefs, path);
	CFRelease(path);
	if ((dict != NULL) && !isA_CFDictionary(dict)) {
		return NULL;
	}

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

	n = (dict != NULL) ? CFDictionaryGetCount(dict) : 0;
	if (n > 0) {
		CFIndex		i;
		const void *    keys_q[N_QUICK];
		const void **   keys	= keys_q;

		if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
			keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
		}
		CFDictionaryGetKeysAndValues(dict, keys, NULL);
		for (i = 0; i < n; i++) {
			CFArrayRef	components;
			CFStringRef	link;

			path = SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL,
										 setPrivate->setID,
										 (CFStringRef)keys[i],
										 NULL);
			link = SCPreferencesPathGetLink(setPrivate->prefs, path);
			CFRelease(path);
			if (link == NULL) {
				SC_log(LOG_INFO, "service \"%@\" for set \"%@\" is not a link",
				       keys[i],
				       setPrivate->setID);
				continue;	 // if the service is not a link
			}

			components = CFStringCreateArrayBySeparatingStrings(NULL, link, CFSTR("/"));
			if (CFArrayGetCount(components) == 3) {
				CFStringRef serviceID;

				serviceID = CFArrayGetValueAtIndex(components, 2);
				path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,		// allocator
										      serviceID,	// service
										      NULL);		// entity
				if (CFEqual(path, link)) {
					SCNetworkServicePrivateRef	servicePrivate;

					servicePrivate = __SCNetworkServiceCreatePrivate(NULL,
											 setPrivate->prefs,
											 serviceID,
											 NULL);
					CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
					CFRelease(servicePrivate);
				}
				CFRelease(path);
			}
			CFRelease(components);
		}
		if (keys != keys_q) {
			CFAllocatorDeallocate(NULL, keys);
		}
	}

	return array;
}
CFDataRef createMkext1ForArch(const NXArchInfo * arch, CFArrayRef archiveKexts,
    boolean_t compress)
{
    CFMutableDataRef       result            = NULL;
    CFMutableDictionaryRef kextsByIdentifier = NULL;
    Mkext1Context          context;
    mkext1_header        * mkextHeader       = NULL;  // do not free
    const uint8_t        * adler_point = 0;
    CFIndex count, i;

    result = CFDataCreateMutable(kCFAllocatorDefault, /* capaacity */ 0);
    if (!result || !createCFMutableDictionary(&kextsByIdentifier)) {
        OSKextLogMemError();
        goto finish;
    }

   /* mkext1 can only contain 1 kext for a given bundle identifier, so we
    * have to pick out the most recent versions.
    */
    count = CFArrayGetCount(archiveKexts);
    for (i = 0; i < count; i++) {
        OSKextRef   theKext = (OSKextRef)CFArrayGetValueAtIndex(archiveKexts, i);
        CFStringRef bundleIdentifier = OSKextGetIdentifier(theKext);
        OSKextRef   savedKext = (OSKextRef)CFDictionaryGetValue(kextsByIdentifier,
            bundleIdentifier);
        OSKextVersion thisVersion, savedVersion;


        if (!OSKextSupportsArchitecture(theKext, arch)) {
            continue;
        }

        if (!savedKext) {
            CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext);
            continue;
        }
        
        thisVersion = OSKextGetVersion(theKext);
        savedVersion = OSKextGetVersion(savedKext);
        
        if (thisVersion > savedVersion) {
            CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext);
        }
    }

   /* Add room for the mkext header and kext descriptors.
    */
    CFDataSetLength(result, sizeof(mkext1_header) +
        CFDictionaryGetCount(kextsByIdentifier) * sizeof(mkext_kext));

    context.mkext = result;
    context.kextIndex = 0;
    context.compressOffset = (uint32_t)CFDataGetLength(result);
    context.arch = arch;
    context.fatal = false;
    context.compress = compress;
    CFDictionaryApplyFunction(kextsByIdentifier, addToMkext1, &context);
    if (context.fatal) {
        SAFE_RELEASE_NULL(result);
        goto finish;
    }

    mkextHeader = (mkext1_header *)CFDataGetBytePtr(result);
    mkextHeader->magic = OSSwapHostToBigInt32(MKEXT_MAGIC);
    mkextHeader->signature = OSSwapHostToBigInt32(MKEXT_SIGN);
    mkextHeader->version = OSSwapHostToBigInt32(0x01008000);   // 'vers' 1.0.0
    mkextHeader->numkexts =
        OSSwapHostToBigInt32((__uint32_t)CFDictionaryGetCount(kextsByIdentifier));
    mkextHeader->cputype = OSSwapHostToBigInt32(arch->cputype);
    mkextHeader->cpusubtype = OSSwapHostToBigInt32(arch->cpusubtype);
    mkextHeader->length = OSSwapHostToBigInt32((__uint32_t)CFDataGetLength(result));

    adler_point = (UInt8 *)&mkextHeader->version;
    mkextHeader->adler32 = OSSwapHostToBigInt32(local_adler32(
        (UInt8 *)&mkextHeader->version,
        (int)(CFDataGetLength(result) - (adler_point - (uint8_t *)mkextHeader))));

    OSKextLog(/* kext */ NULL, kOSKextLogProgressLevel | kOSKextLogArchiveFlag,
        "Created mkext for %s containing %lu kexts.",
        arch->name,
        CFDictionaryGetCount(kextsByIdentifier));

finish:
    SAFE_RELEASE(kextsByIdentifier);
    return result;
}
bool FLACMetadata::WriteMetadata(CFErrorRef *error)
{
	UInt8 buf [PATH_MAX];
	if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX))
		return false;
	
	FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();
	
	// ENOMEM sux
	if(NULL == chain)
		return false;
	
	if(!FLAC__metadata_chain_read(chain, reinterpret_cast<const char *>(buf))) {
		
		// Attempt to provide a descriptive error message
		if(NULL != error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			switch(FLAC__metadata_chain_status(chain)) {
				case FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
					
				case FLAC__METADATA_CHAIN_STATUS_BAD_METADATA:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file contains bad metadata."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
					
				default:
				{
					CFStringRef displayName = CreateDisplayNameForURL(mURL);
					CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																	   NULL, 
																	   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																	   displayName);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedDescriptionKey, 
										 errorString);
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedFailureReasonKey, 
										 CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""));
					
					CFDictionarySetValue(errorDictionary, 
										 kCFErrorLocalizedRecoverySuggestionKey, 
										 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
					
					CFRelease(errorString), errorString = NULL;
					CFRelease(displayName), displayName = NULL;
					
					break;
				}
			}
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataFileFormatNotRecognizedError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;
		}
		
		FLAC__metadata_chain_delete(chain), chain = NULL;
		
		return false;
	}
	
	FLAC__metadata_chain_sort_padding(chain);
	
	FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new();
	
	if(NULL == iterator) {
		FLAC__metadata_chain_delete(chain), chain = NULL;

		return false;
	}
	
	FLAC__metadata_iterator_init(iterator, chain);
	
	// Seek to the vorbis comment block if it exists
	while(FLAC__METADATA_TYPE_VORBIS_COMMENT != FLAC__metadata_iterator_get_block_type(iterator)) {
		if(!FLAC__metadata_iterator_next(iterator))
			break; // Already at end
	}
	
	FLAC__StreamMetadata *block = NULL;
	
	// If there isn't a vorbis comment block add one
	if(FLAC__METADATA_TYPE_VORBIS_COMMENT != FLAC__metadata_iterator_get_block_type(iterator)) {
		
		// The padding block will be the last block if it exists; add the comment block before it
		if(FLAC__METADATA_TYPE_PADDING == FLAC__metadata_iterator_get_block_type(iterator))
			FLAC__metadata_iterator_prev(iterator);
		
		block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
		
		if(NULL == block) {
			FLAC__metadata_chain_delete(chain), chain = NULL;
			FLAC__metadata_iterator_delete(iterator), iterator = NULL;

			return false;
		}
		
		// Add our metadata
		if(!FLAC__metadata_iterator_insert_block_after(iterator, block)) {
			if(NULL != error) {
				CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																				   32,
																				   &kCFTypeDictionaryKeyCallBacks,
																				   &kCFTypeDictionaryValueCallBacks);

				CFStringRef displayName = CreateDisplayNameForURL(mURL);
				CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
																   NULL, 
																   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
																   displayName);
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedDescriptionKey, 
									 errorString);
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedFailureReasonKey, 
									 CFCopyLocalizedString(CFSTR("Unable to write metadata"), ""));
				
				CFDictionarySetValue(errorDictionary, 
									 kCFErrorLocalizedRecoverySuggestionKey, 
									 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
				
				CFRelease(errorString), errorString = NULL;
				CFRelease(displayName), displayName = NULL;

				*error = CFErrorCreate(kCFAllocatorDefault, 
									   AudioMetadataErrorDomain, 
									   AudioMetadataInputOutputError, 
									   errorDictionary);
				
				CFRelease(errorDictionary), errorDictionary = NULL;				
			}
			
			FLAC__metadata_chain_delete(chain), chain = NULL;
			FLAC__metadata_iterator_delete(iterator), iterator = NULL;
			
			return false;
		}
	}
	else
		block = FLAC__metadata_iterator_get_block(iterator);
	
	// Standard tags
	SetVorbisComment(block, "ALBUM", GetAlbumTitle());
	SetVorbisComment(block, "ARTIST", GetArtist());
	SetVorbisComment(block, "ALBUMARTIST", GetAlbumArtist());
	SetVorbisComment(block, "COMPOSER", GetComposer());
	SetVorbisComment(block, "GENRE", GetGenre());
	SetVorbisComment(block, "DATE", GetReleaseDate());
	SetVorbisComment(block, "DESCRIPTION", GetComment());
	SetVorbisComment(block, "TITLE", GetTitle());
	SetVorbisCommentNumber(block, "TRACKNUMBER", GetTrackNumber());
	SetVorbisCommentNumber(block, "TRACKTOTAL", GetTrackTotal());
	SetVorbisCommentBoolean(block, "COMPILATION", GetCompilation());
	SetVorbisCommentNumber(block, "DISCNUMBER", GetDiscNumber());
	SetVorbisCommentNumber(block, "DISCTOTAL", GetDiscTotal());
	SetVorbisComment(block, "ISRC", GetISRC());
	SetVorbisComment(block, "MCN", GetMCN());

	// Additional metadata
	CFDictionaryRef additionalMetadata = GetAdditionalMetadata();
	if(NULL != additionalMetadata) {
		CFIndex count = CFDictionaryGetCount(additionalMetadata);
		
		const void * keys [count];
		const void * values [count];
		
		CFDictionaryGetKeysAndValues(additionalMetadata, 
									 reinterpret_cast<const void **>(keys), 
									 reinterpret_cast<const void **>(values));
		
		for(CFIndex i = 0; i < count; ++i) {
			CFIndex keySize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(reinterpret_cast<CFStringRef>(keys[i])), kCFStringEncodingASCII);
			char key [keySize + 1];
			       
			if(!CFStringGetCString(reinterpret_cast<CFStringRef>(keys[i]), key, keySize + 1, kCFStringEncodingASCII)) {
				log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioMetadata.FLAC");
				LOG4CXX_WARN(logger, "CFStringGetCString() failed");
				continue;
			}
			
			SetVorbisComment(block, key, reinterpret_cast<CFStringRef>(values[i]));
		}
	}
	
	// ReplayGain info
	SetVorbisCommentDouble(block, "REPLAYGAIN_REFERENCE_LOUDNESS", GetReplayGainReferenceLoudness(), CFSTR("%2.1f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_TRACK_GAIN", GetReplayGainReferenceLoudness(), CFSTR("%+2.2f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_TRACK_PEAK", GetReplayGainTrackGain(), CFSTR("%1.8f"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_ALBUM_GAIN", GetReplayGainAlbumGain(), CFSTR("%+2.2f dB"));
	SetVorbisCommentDouble(block, "REPLAYGAIN_ALBUM_PEAK", GetReplayGainAlbumPeak(), CFSTR("%1.8f"));
	
	// Write the new metadata to the file
	if(!FLAC__metadata_chain_write(chain, true, false)) {
		if(NULL != error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);

			CFStringRef displayName = CreateDisplayNameForURL(mURL);
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""), 
															   displayName);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Unable to write metadata"), ""));
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
			
			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioMetadataErrorDomain, 
								   AudioMetadataInputOutputError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;				
		}
		
		FLAC__metadata_chain_delete(chain), chain = NULL;
		FLAC__metadata_iterator_delete(iterator), iterator = NULL;
		
		return false;
	}
	
	FLAC__metadata_chain_delete(chain), chain = NULL;
	FLAC__metadata_iterator_delete(iterator), iterator = NULL;
	
	MergeChangedMetadataIntoMetadata();
	
	return true;
}
Beispiel #28
0
static void
apple_register_profiles(
    cupsd_printer_t *p)			/* I - Printer */
{
  int			i;		/* Looping var */
  char			ppdfile[1024],	/* PPD filename */
			iccfile[1024],	/* ICC filename */
			selector[PPD_MAX_NAME];
					/* Profile selection string */
  ppd_file_t		*ppd;		/* PPD file */
  ppd_attr_t		*attr,		/* Profile attributes */
			*profileid_attr,/* cupsProfileID attribute */
			*q1_attr,	/* ColorModel (or other) qualifier */
			*q2_attr,	/* MediaType (or other) qualifier */
			*q3_attr;	/* Resolution (or other) qualifier */
  char			q_keyword[PPD_MAX_NAME];
					/* Qualifier keyword */
  const char		*q1_choice,	/* ColorModel (or other) choice */
			*q2_choice,	/* MediaType (or other) choice */
			*q3_choice;	/* Resolution (or other) choice */
  ppd_option_t		*cm_option;	/* Color model option */
  ppd_choice_t		*cm_choice;	/* Color model choice */
  int			num_profiles;	/* Number of profiles */
  OSStatus		error = 0;	/* Last error */
  unsigned		device_id,	/* Printer device ID */
			profile_id = 0,	/* Profile ID */
			default_profile_id = 0;
					/* Default profile ID */
  CFMutableDictionaryRef device_name;	/* Printer device name dictionary */
  CFStringRef		printer_name;	/* Printer name string */
  cups_array_t		*languages;	/* Languages array */
  CFMutableDictionaryRef profiles,	/* Dictionary of profiles */
			profile;	/* Current profile info dictionary */
  CFStringRef		dict_key;	/* Key in factory profile dictionary */


 /*
  * Make sure ColorSync is available...
  */

  if (&ColorSyncRegisterDevice == NULL)
    return;

 /*
  * Try opening the PPD file for this printer...
  */

  snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
  if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_ICC_PROFILES)) == NULL)
    return;

 /*
  * See if we have any profiles...
  */

  for (num_profiles = 0, attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
       attr;
       attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
    if (attr->spec[0] && attr->value && attr->value[0])
    {
      if (attr->value[0] != '/')
	snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
		 attr->value);
      else
	strlcpy(iccfile, attr->value, sizeof(iccfile));

      if (access(iccfile, 0))
      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "%s: ICC Profile \"%s\" does not exist.", p->name,
                        iccfile);
        cupsdSetPrinterReasons(p, "+cups-missing-filter-warning");
	continue;
      }

      num_profiles ++;
    }

 /*
  * Create a dictionary for the factory profiles...
  */

  profiles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
				       &kCFTypeDictionaryKeyCallBacks,
				       &kCFTypeDictionaryValueCallBacks);
  if (!profiles)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
		    "Unable to allocate memory for factory profiles.");
    ppdClose(ppd);
    return;
  }

 /*
  * If we have profiles, add them...
  */

  if (num_profiles > 0)
  {
   /*
    * For CUPS PPDs, figure out the default profile selector values...
    */

    if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
	attr->value && attr->value[0])
    {
      snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
      q1_attr = ppdFindAttr(ppd, q_keyword, NULL);
    }
    else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL)
      q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);

    if (q1_attr && q1_attr->value && q1_attr->value[0])
      q1_choice = q1_attr->value;
    else
      q1_choice = "";

    if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
	attr->value && attr->value[0])
    {
      snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
      q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
    }
    else
      q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);

    if (q2_attr && q2_attr->value && q2_attr->value[0])
      q2_choice = q2_attr->value;
    else
      q2_choice = NULL;

    if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
	attr->value && attr->value[0])
    {
      snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
      q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
    }
    else
      q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);

    if (q3_attr && q3_attr->value && q3_attr->value[0])
      q3_choice = q3_attr->value;
    else
      q3_choice = NULL;

   /*
    * Loop through the profiles listed in the PPD...
    */

    languages = _ppdGetLanguages(ppd);

    for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
	 attr;
	 attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
      if (attr->spec[0] && attr->value && attr->value[0])
      {
       /*
        * Add this profile...
	*/

        if (attr->value[0] != '/')
	  snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
	           attr->value);
        else
	  strlcpy(iccfile, attr->value, sizeof(iccfile));

        if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser,
	                   cupsdLogFCMessage, p))
	  iccfile[0] = '\0';

	cupsArraySave(ppd->sorted_attrs);

	if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
					  attr->spec)) != NULL &&
	    profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
	  profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
	else
	  profile_id = _ppdHashName(attr->spec);

	cupsArrayRestore(ppd->sorted_attrs);

	profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
					    &kCFTypeDictionaryKeyCallBacks,
					    &kCFTypeDictionaryValueCallBacks);
	if (!profile)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
	                  "Unable to allocate memory for color profile.");
	  CFRelease(profiles);
	  ppdClose(ppd);
	  return;
	}

	apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
	                   attr->text[0] ? attr->text : attr->spec, iccfile);

	dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
	                                    CFSTR("%u"), profile_id);
	if (dict_key)
	{
	  CFDictionarySetValue(profiles, dict_key, profile);
	  CFRelease(dict_key);
	}

	CFRelease(profile);

       /*
        * See if this is the default profile...
	*/

        if (!default_profile_id && q1_choice && q2_choice && q3_choice)
	{
	  snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
	           q3_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q1_choice && q2_choice)
	{
	  snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q1_choice && q3_choice)
	{
	  snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q1_choice)
	{
	  snprintf(selector, sizeof(selector), "%s..", q1_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q2_choice && q3_choice)
	{
	  snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q2_choice)
	{
	  snprintf(selector, sizeof(selector), ".%s.", q2_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}

        if (!default_profile_id && q3_choice)
	{
	  snprintf(selector, sizeof(selector), "..%s", q3_choice);
	  if (!strcmp(selector, attr->spec))
	    default_profile_id = profile_id;
	}
      }

    _ppdFreeLanguages(languages);
  }
  else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL)
  {
   /*
    * Extract profiles from ColorModel option...
    */

    const char *profile_name;		/* Name of generic profile */


    num_profiles = cm_option->num_choices;

    for (i = cm_option->num_choices, cm_choice = cm_option->choices;
         i > 0;
	 i --, cm_choice ++)
    {
      if (!strcmp(cm_choice->choice, "Gray") ||
          !strcmp(cm_choice->choice, "Black"))
        profile_name = "Gray";
      else if (!strcmp(cm_choice->choice, "RGB") ||
               !strcmp(cm_choice->choice, "CMY"))
        profile_name = "RGB";
      else if (!strcmp(cm_choice->choice, "CMYK") ||
               !strcmp(cm_choice->choice, "KCMY"))
        profile_name = "CMYK";
      else
        profile_name = "DeviceN";

      snprintf(selector, sizeof(selector), "%s..", profile_name);
      profile_id = _ppdHashName(selector);

      profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
					  &kCFTypeDictionaryKeyCallBacks,
					  &kCFTypeDictionaryValueCallBacks);
      if (!profile)
      {
	cupsdLogMessage(CUPSD_LOG_ERROR,
			"Unable to allocate memory for color profile.");
	CFRelease(profiles);
	ppdClose(ppd);
	return;
      }

      apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
                         cm_choice->text, NULL);

      dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
                                          CFSTR("%u"), profile_id);
      if (dict_key)
      {
	CFDictionarySetValue(profiles, dict_key, profile);
	CFRelease(dict_key);
      }

      CFRelease(profile);

      if (cm_choice->marked)
        default_profile_id = profile_id;
    }
  }
  else
  {
   /*
    * Use the default colorspace...
    */

    attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);

    num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;

   /*
    * Add the grayscale profile first.  We always have a grayscale profile.
    */

    profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
				        &kCFTypeDictionaryKeyCallBacks,
				        &kCFTypeDictionaryValueCallBacks);

    if (!profile)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unable to allocate memory for color profile.");
      CFRelease(profiles);
      ppdClose(ppd);
      return;
    }

    profile_id = _ppdHashName("Gray..");
    apple_init_profile(ppd, NULL, profile, profile_id, "Gray", "Gray", NULL);

    dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
                                        profile_id);
    if (dict_key)
    {
      CFDictionarySetValue(profiles, dict_key, profile);
      CFRelease(dict_key);
    }

    CFRelease(profile);

   /*
    * Then add the RGB/CMYK/DeviceN color profile...
    */

    profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
				        &kCFTypeDictionaryKeyCallBacks,
				        &kCFTypeDictionaryValueCallBacks);

    if (!profile)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unable to allocate memory for color profile.");
      CFRelease(profiles);
      ppdClose(ppd);
      return;
    }

    switch (ppd->colorspace)
    {
      default :
      case PPD_CS_RGB :
      case PPD_CS_CMY :
          profile_id = _ppdHashName("RGB..");
          apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB",
	                     NULL);
          break;

      case PPD_CS_RGBK :
      case PPD_CS_CMYK :
          profile_id = _ppdHashName("CMYK..");
          apple_init_profile(ppd, NULL, profile, profile_id, "CMYK", "CMYK",
	                     NULL);
          break;

      case PPD_CS_GRAY :
          if (attr)
            break;

      case PPD_CS_N :
          profile_id = _ppdHashName("DeviceN..");
          apple_init_profile(ppd, NULL, profile, profile_id, "DeviceN",
	                     "DeviceN", NULL);
          break;
    }

    if (CFDictionaryGetCount(profile) > 0)
    {
      dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
                                          CFSTR("%u"), profile_id);
      if (dict_key)
      {
        CFDictionarySetValue(profiles, dict_key, profile);
        CFRelease(dict_key);
      }
    }

    CFRelease(profile);
  }

  if (num_profiles > 0)
  {
   /*
    * Make sure we have a default profile ID...
    */

    if (!default_profile_id)
      default_profile_id = profile_id;	/* Last profile */

    dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
                                        default_profile_id);
    if (dict_key)
    {
      CFDictionarySetValue(profiles, kColorSyncDeviceDefaultProfileID,
                           dict_key);
      CFRelease(dict_key);
    }

   /*
    * Get the device ID hash and pathelogical name dictionary.
    */

    cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
		    p->name);

    device_id    = _ppdHashName(p->name);
    device_name  = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
					     &kCFTypeDictionaryKeyCallBacks,
					     &kCFTypeDictionaryValueCallBacks);
    printer_name = CFStringCreateWithCString(kCFAllocatorDefault,
                                             p->name, kCFStringEncodingUTF8);

    if (device_name && printer_name)
    {
     /*
      * Register the device with ColorSync...
      */

      CFTypeRef		deviceDictKeys[] =
      {					/* Device keys */
        kColorSyncDeviceDescriptions,
	kColorSyncFactoryProfiles,
	kColorSyncDeviceUserScope,
	kColorSyncDeviceHostScope
      };
      CFTypeRef 	deviceDictVals[] =
      {					/* Device values */
        device_name,
	profiles,
	kCFPreferencesAnyUser,
	kCFPreferencesCurrentHost
      };
      CFDictionaryRef	deviceDict;	/* Device dictionary */
      CFUUIDRef		deviceUUID;	/* Device UUID */

      CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);

      deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
				      (const void **)deviceDictKeys,
				      (const void **)deviceDictVals,
				      sizeof(deviceDictKeys) /
				          sizeof(deviceDictKeys[0]),
				      &kCFTypeDictionaryKeyCallBacks,
				      &kCFTypeDictionaryValueCallBacks);
      deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id);

      if (!deviceDict || !deviceUUID ||
	  !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
				   deviceDict))
	error = 1001;

      if (deviceUUID)
        CFRelease(deviceUUID);

      if (deviceDict)
        CFRelease(deviceDict);
    }
    else
      error = 1000;

   /*
    * Clean up...
    */

    if (error != noErr)
      cupsdLogMessage(CUPSD_LOG_ERROR,
		      "Unable to register ICC color profiles for \"%s\": %d",
		      p->name, (int)error);

    if (printer_name)
      CFRelease(printer_name);

    if (device_name)
      CFRelease(device_name);
  }

 /*
  * Free any memory we used...
  */

  CFRelease(profiles);

  ppdClose(ppd);
}
bool UserObjectImp::toBoolean(ExecState *exec) const
{
    bool result = false;
    JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
    CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
    if (cfValue)
    {
        CFTypeID cfType = CFGetTypeID(cfValue);  // toPrimitive
        if (cfValue == GetCFNull())
        {
            //
        }
        else if (cfType == CFBooleanGetTypeID())
        {
            if (cfValue == kCFBooleanTrue)
            {
                result = true;
            }
        }
        else if (cfType == CFStringGetTypeID())
        {
            if (CFStringGetLength((CFStringRef)cfValue))
            {
                result = true;
            }
        }
        else if (cfType == CFNumberGetTypeID())
        {
            if (cfValue != kCFNumberNaN)
            {
                double d;
                if (CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d))
                {
                    if (d != 0)
                    {
                        result = true;
                    }
                }
            }
        }
        else if (cfType == CFArrayGetTypeID())
        {
            if (CFArrayGetCount((CFArrayRef)cfValue))
            {
                result = true;
            }
        }
        else if (cfType == CFDictionaryGetTypeID())
        {
            if (CFDictionaryGetCount((CFDictionaryRef)cfValue))
            {
                result = true;
            }
        }
        else if (cfType == CFSetGetTypeID())
        {
            if (CFSetGetCount((CFSetRef)cfValue))
            {
                result = true;
            }
        }
        else if (cfType == CFURLGetTypeID())
        {
            CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
            if (absURL)
            {
                CFStringRef cfStr = CFURLGetString(absURL);
                if (cfStr && CFStringGetLength(cfStr))
                {
                    result = true;
                }
                ReleaseCFType(absURL);
            }
        }
    }
    if (jsObjPtr) jsObjPtr->Release();
    ReleaseCFType(cfValue);
    return result;
}
bool PluginPackage::fetchInfo()
{
    if (!load())
        return false;

    WTF::RetainPtr<CFDictionaryRef> mimeDict;

    WTF::RetainPtr<CFTypeRef> mimeTypesFileName = CFBundleGetValueForInfoDictionaryKey(m_module, CFSTR("WebPluginMIMETypesFilename"));
    if (mimeTypesFileName && CFGetTypeID(mimeTypesFileName.get()) == CFStringGetTypeID()) {

        WTF::RetainPtr<CFStringRef> fileName = (CFStringRef)mimeTypesFileName.get();
        WTF::RetainPtr<CFStringRef> homeDir = homeDirectoryPath().createCFString();
        WTF::RetainPtr<CFStringRef> path = CFStringCreateWithFormat(0, 0, CFSTR("%@/Library/Preferences/%@"), homeDir.get(), fileName.get());

        WTF::RetainPtr<CFDictionaryRef> plist = readPListFile(path.get(), /*createFile*/ false, m_module);
        if (plist) {
            // If the plist isn't localized, have the plug-in recreate it in the preferred language.
            WTF::RetainPtr<CFStringRef> localizationName =
                (CFStringRef)CFDictionaryGetValue(plist.get(), CFSTR("WebPluginLocalizationName"));
            CFLocaleRef locale = CFLocaleCopyCurrent();
            if (localizationName != CFLocaleGetIdentifier(locale))
                plist = readPListFile(path.get(), /*createFile*/ true, m_module);

            CFRelease(locale);
        } else {
            // Plist doesn't exist, ask the plug-in to create it.
            plist = readPListFile(path.get(), /*createFile*/ true, m_module);
        }

        mimeDict = (CFDictionaryRef)CFDictionaryGetValue(plist.get(), CFSTR("WebPluginMIMETypes"));
    }

    if (!mimeDict)
        mimeDict = (CFDictionaryRef)CFBundleGetValueForInfoDictionaryKey(m_module, CFSTR("WebPluginMIMETypes"));

    if (mimeDict) {
        CFIndex propCount = CFDictionaryGetCount(mimeDict.get());
        Vector<const void*, 128> keys(propCount);
        Vector<const void*, 128> values(propCount);
        CFDictionaryGetKeysAndValues(mimeDict.get(), keys.data(), values.data());
        for (int i = 0; i < propCount; ++i) {
            String mimeType = (CFStringRef)keys[i];
            mimeType = mimeType.lower();

            WTF::RetainPtr<CFDictionaryRef> extensionsDict = (CFDictionaryRef)values[i];

            WTF:RetainPtr<CFNumberRef> enabled = (CFNumberRef)CFDictionaryGetValue(extensionsDict.get(), CFSTR("WebPluginTypeEnabled"));
            if (enabled) {
                int enabledValue = 0;
                if (CFNumberGetValue(enabled.get(), kCFNumberIntType, &enabledValue) && enabledValue == 0)
                    continue;
            }

            Vector<String> mimeExtensions;
            WTF::RetainPtr<CFArrayRef> extensions = (CFArrayRef)CFDictionaryGetValue(extensionsDict.get(), CFSTR("WebPluginExtensions"));
            if (extensions) {
                CFIndex extensionCount = CFArrayGetCount(extensions.get());
                for (CFIndex i = 0; i < extensionCount; ++i) {
                    String extension =(CFStringRef)CFArrayGetValueAtIndex(extensions.get(), i);
                    extension = extension.lower();
                    mimeExtensions.append(extension);
                }
            }
            m_mimeToExtensions.set(mimeType, mimeExtensions);

            String description = (CFStringRef)CFDictionaryGetValue(extensionsDict.get(), CFSTR("WebPluginTypeDescription"));
            m_mimeToDescriptions.set(mimeType, description);
        }

        m_name = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(m_module, CFSTR("WebPluginName"));
        m_description = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(m_module, CFSTR("WebPluginDescription"));

    } else {
        int resFile = CFBundleOpenBundleResourceMap(m_module);

        UseResFile(resFile);

        Vector<String> mimes = stringListFromResourceId(MIMEListStringStringNumber);

        if (mimes.size() % 2 != 0)
            return false;

        Vector<String> descriptions = stringListFromResourceId(MIMEDescriptionStringNumber);
        if (descriptions.size() != mimes.size() / 2)
            return false;

        for (size_t i = 0;  i < mimes.size(); i += 2) {
            String mime = mimes[i].lower();
            Vector<String> extensions;
            mimes[i + 1].lower().split(UChar(','), extensions);

            m_mimeToExtensions.set(mime, extensions);

            m_mimeToDescriptions.set(mime, descriptions[i / 2]);
        }

        Vector<String> names = stringListFromResourceId(PluginNameOrDescriptionStringNumber);
        if (names.size() == 2) {
            m_description = names[0];
            m_name = names[1];
        }

        CFBundleCloseBundleResourceMap(m_module, resFile);
    }

    LOG(Plugins, "PluginPackage::fetchInfo(): Found plug-in '%s'", m_name.utf8().data());
    if (isPluginBlacklisted()) {
        LOG(Plugins, "\tPlug-in is blacklisted!");
        return false;
    }

    return true;
}