void HTTP_Stream::parseICYStream(const UInt8 *buf, const CFIndex bufSize) { HS_TRACE("Parsing an IceCast stream, received %li bytes\n", bufSize); CFIndex offset = 0; CFIndex bytesFound = 0; if (!m_icyHeadersRead) { HS_TRACE("ICY headers not read, reading\n"); for (; offset < bufSize; offset++) { if (m_icyHeaderCR && buf[offset] == '\n') { if (bytesFound > 0) { m_icyHeaderLines.push_back(createMetaDataStringWithMostReasonableEncoding(&buf[offset-bytesFound-1], bytesFound)); bytesFound = 0; HS_TRACE_CFSTRING(m_icyHeaderLines[m_icyHeaderLines.size()-1]); continue; } HS_TRACE("End of ICY headers\n"); m_icyHeadersRead = true; break; } if (buf[offset] == '\r') { m_icyHeaderCR = true; continue; } else { m_icyHeaderCR = false; } bytesFound++; } } else if (!m_icyHeadersParsed) { HS_TRACE("ICY headers not parsed, parsing\n"); const CFStringRef icyContentTypeHeader = CFSTR("content-type:"); const CFStringRef icyMetaDataHeader = CFSTR("icy-metaint:"); const CFStringRef icyNameHeader = CFSTR("icy-name:"); const CFIndex icyContenTypeHeaderLength = CFStringGetLength(icyContentTypeHeader); const CFIndex icyMetaDataHeaderLength = CFStringGetLength(icyMetaDataHeader); const CFIndex icyNameHeaderLength = CFStringGetLength(icyNameHeader); for (std::vector<CFStringRef>::iterator h = m_icyHeaderLines.begin(); h != m_icyHeaderLines.end(); ++h) { CFStringRef line = *h; const CFIndex lineLength = CFStringGetLength(line); if (lineLength == 0) { continue; } HS_TRACE_CFSTRING(line); if (CFStringCompareWithOptions(line, icyContentTypeHeader, CFRangeMake(0, icyContenTypeHeaderLength), 0) == kCFCompareEqualTo) { if (m_contentType) { CFRelease(m_contentType), m_contentType = 0; } m_contentType = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyContenTypeHeaderLength, lineLength - icyContenTypeHeaderLength)); } if (CFStringCompareWithOptions(line, icyMetaDataHeader, CFRangeMake(0, icyMetaDataHeaderLength), 0) == kCFCompareEqualTo) { CFStringRef metadataInterval = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyMetaDataHeaderLength, lineLength - icyMetaDataHeaderLength)); if (metadataInterval) { m_icyMetaDataInterval = CFStringGetIntValue(metadataInterval); CFRelease(metadataInterval); } else { m_icyMetaDataInterval = 0; } } if (CFStringCompareWithOptions(line, icyNameHeader, CFRangeMake(0, icyNameHeaderLength), 0) == kCFCompareEqualTo) { if (m_icyName) { CFRelease(m_icyName); } m_icyName = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyNameHeaderLength, lineLength - icyNameHeaderLength)); } } m_icyHeadersParsed = true; offset++; if (m_delegate) { m_delegate->streamIsReadyRead(); } } Stream_Configuration *config = Stream_Configuration::configuration(); if (!m_icyReadBuffer) { m_icyReadBuffer = new UInt8[config->httpConnectionBufferSize]; } HS_TRACE("Reading ICY stream for playback\n"); UInt32 i=0; for (; offset < bufSize; offset++) { // is this a metadata byte? if (m_metaDataBytesRemaining > 0) { m_metaDataBytesRemaining--; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; if (m_delegate && !m_icyMetaData.empty()) { std::map<CFStringRef,CFStringRef> metadataMap; CFStringRef metaData = createMetaDataStringWithMostReasonableEncoding(&m_icyMetaData[0], m_icyMetaData.size()); if (!metaData) { // Metadata encoding failed, cannot parse. m_icyMetaData.clear(); continue; } CFArrayRef tokens = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, metaData, CFSTR(";")); for (CFIndex i=0, max=CFArrayGetCount(tokens); i < max; i++) { CFStringRef token = (CFStringRef) CFArrayGetValueAtIndex(tokens, i); CFRange foundRange; if (CFStringFindWithOptions(token, CFSTR("='"), CFRangeMake(0, CFStringGetLength(token)), NULL, &foundRange) == true) { CFRange keyRange = CFRangeMake(0, foundRange.location); CFStringRef metadaKey = CFStringCreateWithSubstring(kCFAllocatorDefault, token, keyRange); CFRange valueRange = CFRangeMake(foundRange.location + 2, CFStringGetLength(token) - keyRange.length - 3); CFStringRef metadaValue = CFStringCreateWithSubstring(kCFAllocatorDefault, token, valueRange); metadataMap[metadaKey] = metadaValue; } } CFRelease(tokens); CFRelease(metaData); if (m_icyName) { metadataMap[CFSTR("IcecastStationName")] = CFStringCreateCopy(kCFAllocatorDefault, m_icyName); } m_delegate->streamMetaDataAvailable(metadataMap); } m_icyMetaData.clear(); continue; } m_icyMetaData.push_back(buf[offset]); continue; } // is this the interval byte? if (m_icyMetaDataInterval > 0 && m_dataByteReadCount == m_icyMetaDataInterval) { m_metaDataBytesRemaining = buf[offset] * 16; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; } continue; } // a data byte m_dataByteReadCount++; m_icyReadBuffer[i++] = buf[offset]; } if (m_delegate && i > 0) { m_delegate->streamHasBytesAvailable(m_icyReadBuffer, i); } }
void HTTP_Stream::readCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { HTTP_Stream *THIS = static_cast<HTTP_Stream*>(clientCallBackInfo); Stream_Configuration *config = Stream_Configuration::configuration(); CFStringRef reportedNetworkError = NULL; switch (eventType) { case kCFStreamEventHasBytesAvailable: { if (!THIS->m_httpReadBuffer) { THIS->m_httpReadBuffer = new UInt8[config->httpConnectionBufferSize]; } while (CFReadStreamHasBytesAvailable(stream)) { if (!THIS->m_scheduledInRunLoop) { /* * This is critical - though the stream has data available, * do not try to feed the audio queue with data, if it has * indicated that it doesn't want more data due to buffers * full. */ THIS->m_readPending = true; break; } CFIndex bytesRead = CFReadStreamRead(stream, THIS->m_httpReadBuffer, config->httpConnectionBufferSize); if (CFReadStreamGetStatus(stream) == kCFStreamStatusError || bytesRead < 0) { CFErrorRef streamError = CFReadStreamCopyError(stream); if (streamError) { CFStringRef errorDesc = CFErrorCopyDescription(streamError); if (errorDesc) { reportedNetworkError = CFStringCreateCopy(kCFAllocatorDefault, errorDesc); CFRelease(errorDesc); } CFRelease(streamError); } if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(reportedNetworkError); if (reportedNetworkError) { CFRelease(reportedNetworkError), reportedNetworkError = NULL; } } break; } if (bytesRead > 0) { HS_TRACE("Read %li bytes\n", bytesRead); THIS->parseHttpHeadersIfNeeded(THIS->m_httpReadBuffer, bytesRead); #ifdef INCLUDE_ID3TAG_SUPPORT if (!THIS->m_icyStream && THIS->m_id3Parser->wantData()) { THIS->m_id3Parser->feedData(THIS->m_httpReadBuffer, (UInt32)bytesRead); } #endif if (THIS->m_icyStream) { HS_TRACE("Parsing ICY stream\n"); THIS->parseICYStream(THIS->m_httpReadBuffer, bytesRead); } else { if (THIS->m_delegate) { HS_TRACE("Not an ICY stream; calling the delegate back\n"); THIS->m_delegate->streamHasBytesAvailable(THIS->m_httpReadBuffer, (UInt32)bytesRead); } } } } if (reportedNetworkError) { CFRelease(reportedNetworkError), reportedNetworkError = NULL; } break; } case kCFStreamEventEndEncountered: { if (THIS->m_delegate) { THIS->m_delegate->streamEndEncountered(); } break; } case kCFStreamEventErrorOccurred: { if (THIS->m_delegate) { CFStringRef reportedNetworkError = NULL; CFErrorRef streamError = CFReadStreamCopyError(stream); if (streamError) { CFStringRef errorDesc = CFErrorCopyDescription(streamError); if (errorDesc) { reportedNetworkError = CFStringCreateCopy(kCFAllocatorDefault, errorDesc); CFRelease(errorDesc); } CFRelease(streamError); } THIS->m_delegate->streamErrorOccurred(reportedNetworkError); if (reportedNetworkError) { CFRelease(reportedNetworkError); } } break; } } }
void APSetHash(CFStringRef newHash) { if (hash != NULL) CFRelease(hash); hash = CFStringCreateCopy(kCFAllocatorDefault, newHash); }
void HTTP_Stream::parseHttpHeadersIfNeeded(const UInt8 *buf, const CFIndex bufSize) { if (m_httpHeadersParsed) { return; } m_httpHeadersParsed = true; /* If the response has the "ICY 200 OK" string, * we are dealing with the ShoutCast protocol. * The HTTP headers won't be available. */ if (bufSize >= 10 && buf[0] == 0x49 && buf[1] == 0x43 && buf[2] == 0x59 && buf[3] == 0x20 && buf[4] == 0x32 && buf[5] == 0x30 && buf[6] == 0x30 && buf[7] == 0x20 && buf[8] == 0x4F && buf[9] == 0x4B) { m_icyStream = true; HS_TRACE("Detected an IceCast stream\n"); // This is an ICY stream, don't try to parse the HTTP headers return; } HS_TRACE("A regular HTTP stream\n"); CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(m_readStream, kCFStreamPropertyHTTPResponseHeader); if (response) { /* * If the server responded with the icy-metaint header, the response * body will be encoded in the ShoutCast protocol. */ CFStringRef icyMetaIntString = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("icy-metaint")); if (icyMetaIntString) { m_icyStream = true; m_icyHeadersParsed = true; m_icyHeadersRead = true; m_icyMetaDataInterval = CFStringGetIntValue(icyMetaIntString); CFRelease(icyMetaIntString); } HS_TRACE("icy-metaint: %zu\n", m_icyMetaDataInterval); CFStringRef icyNameString = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("icy-name")); if (icyNameString) { if (m_icyName) { CFRelease(m_icyName); } m_icyName = icyNameString; if (m_delegate) { std::map<CFStringRef,CFStringRef> metadataMap; metadataMap[CFSTR("IcecastStationName")] = CFStringCreateCopy(kCFAllocatorDefault, m_icyName); m_delegate->streamMetaDataAvailable(metadataMap); } } if (m_contentType) { CFRelease(m_contentType); } m_contentType = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Type")); HS_TRACE("Content-type: "); HS_TRACE_CFSTRING(m_contentType); CFStringRef contentLengthString = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Length")); if (contentLengthString) { m_contentLength = CFStringGetIntValue(contentLengthString); CFRelease(contentLengthString); } CFRelease(response); } if (m_delegate) { m_delegate->streamIsReadyRead(); } }
CFStringRef APHash(void) { return CFStringCreateCopy(kCFAllocatorDefault, hash); }
Boolean SCBondInterfaceSetLocalizedDisplayName(SCBondInterfaceRef bond, CFStringRef newName) { SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)bond; Boolean ok = TRUE; if (!isA_SCBondInterface(bond)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if ((newName != NULL) && !isA_CFString(newName)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // set name in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); if (newName != NULL) { CFDictionarySetValue(newDict, kSCPropUserDefinedName, newName); } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); } if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } // set name in the SCBondInterfaceRef if (ok) { if (interfacePrivate->localized_name != NULL) { CFRelease(interfacePrivate->localized_name); interfacePrivate->localized_name = NULL; } if (newName != NULL) { interfacePrivate->localized_name = CFStringCreateCopy(NULL, newName); } } return ok; }
SOSErrorCreate(kSOSErrorBadSignature, error, NULL, CFSTR("Signature didn't verify for %@"), peer)); result = true; error_out: CFReleaseNull(pubKey); return result; } static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, CFDictionaryRef gestalt, SecKeyRef signingKey, CFErrorRef* error, void (^ description_modifier)(CFMutableDictionaryRef description)) { SOSPeerInfoRef pi = CFTypeAllocate(SOSPeerInfo, struct __OpaqueSOSPeerInfo, allocator); pi->gestalt = gestalt; CFRetain(pi->gestalt); pi->version = SOSPeerInfoGetPeerProtocolVersion(pi); pi->transportType = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("KVS")); CFDataRef publicBytes = NULL; CFNumberRef versionNumber = NULL; SecKeyRef publicKey = SecKeyCreatePublicFromPrivate(signingKey); if (publicKey == NULL) { SOSCreateError(kSOSErrorBadKey, CFSTR("Unable to get public"), NULL, error); CFReleaseNull(pi); goto exit; } OSStatus result = SecKeyCopyPublicBytes(publicKey, &publicBytes); if (result != errSecSuccess) { SOSCreateError(kSOSErrorBadKey, CFSTR("Failed to export public bytes"), NULL, error); CFReleaseNull(pi);
static CFStringRef copyVPNInterfaceNAP (char *interface_buf) { CFStringRef interf_key; CFMutableArrayRef interf_keys; CFDictionaryRef dict = NULL; CFIndex i; const void * keys_q[128]; void ** keys = (__typeof__(keys))keys_q; const void * values_q[128]; void ** values = (__typeof__(values))values_q; CFIndex n; CFStringRef vpn_if = NULL; CFStringRef result = NULL; if (!interface_buf) { return NULL; } if (gDynamicStore) { vpn_if = CFStringCreateWithCStringNoCopy(NULL, interface_buf, kCFStringEncodingASCII, kCFAllocatorNull); if (!vpn_if) { // if we could not initialize interface CFString goto done; } interf_keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); // get State:/Network/Interface/<vpn_if>/Airport interf_key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, vpn_if, kSCEntNetAirPort); CFArrayAppendValue(interf_keys, interf_key); CFRelease(interf_key); dict = SCDynamicStoreCopyMultiple(gDynamicStore, interf_keys, NULL); CFRelease(interf_keys); if (!dict) { // if we could not access the SCDynamicStore goto done; } // look for the service which matches the provided prefixes n = CFDictionaryGetCount(dict); if (n <= 0) { goto done; } if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); values = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); } CFDictionaryGetKeysAndValues(dict, (const void **)keys, (const void **)values); for (i=0; i < n; i++) { CFStringRef s_key = (CFStringRef)keys[i]; CFDictionaryRef s_dict = (CFDictionaryRef)values[i]; CFDictionaryRef i_dict = NULL; CFStringRef nap; if (!isA_CFString(s_key) || !isA_CFDictionary(s_dict)) { continue; } i_dict = CFDictionaryGetValue(s_dict, KEY_VPNNETWORKLOCATION_INTERFINFO); if (!isA_CFDictionary(i_dict)) { continue; } nap = CFDictionaryGetValue(i_dict, KEY_VPNNETWORKLOCATION_SSID); if (nap) { result = CFStringCreateCopy(NULL, nap); SCLog(TRUE, LOG_INFO, CFSTR("%s: found nap %@, interf %s"), __FUNCTION__, result, interface_buf); goto done; } } done : if (vpn_if) CFRelease(vpn_if); if (keys != (__typeof__(keys))keys_q) { CFAllocatorDeallocate(NULL, keys); CFAllocatorDeallocate(NULL, values); } if (dict) CFRelease(dict); } return result; }
void AddNeighborhoodToList(char * neighborhood, UInt32 parentID) { CFStringRef tempNeighborhood = NULL; CFComparisonResult result = -1; UInt32 neighborhoodID, i; if (neighborhood) { tempNeighborhood = CFStringCreateWithCString(NULL, neighborhood, CFStringGetSystemEncoding()); if (tempNeighborhood) { // Check if the item is already in our list. If it is, "result" will be kCFCompareEqualTo. for (i = 0; i < kMaxNeighborhoods; i++) { if (gData[i] && gNeighborhoodInfo.parentID[i] == parentID) { result = CFStringCompare(tempNeighborhood, gData[i], kCFCompareCaseInsensitive); if (result == kCFCompareEqualTo) break; } } if (result != kCFCompareEqualTo) { // Only add the item if the parent neighborhood is open and visible in the Data Browser. if ((gNeighborhoodInfo.isNeighborhoodOpen[parentID - 1] && gNeighborhoodInfo.isNeighborhoodVisible[parentID - 1]) || parentID == 0) { neighborhoodID = IncrementAtomic(&gNeighborhoodInfo.neighborhoodCount); if (++neighborhoodID < kMaxNeighborhoods) { gNeighborhoodInfo.parentID[neighborhoodID - 1] = parentID; gData[neighborhoodID - 1] = CFStringCreateCopy(NULL, tempNeighborhood); AddDataBrowserItems(gDataBrowserControl, parentID, 1, &neighborhoodID, kNameColumn); if (parentID == kDataBrowserNoItem) { gNeighborhoodInfo.isDefaultNeighborhood[neighborhoodID - 1] = true; } else { gNeighborhoodInfo.isDefaultNeighborhood[neighborhoodID - 1] = false; } } else { DecrementAtomic(&gNeighborhoodInfo.neighborhoodCount); } } } else if (result == kCFCompareEqualTo) { if (gNeighborhoodInfo.isNeighborhoodOpen[parentID - 1] && gNeighborhoodInfo.isNeighborhoodVisible[parentID - 1]) { neighborhoodID = i + 1; if (gNeighborhoodInfo.isNeighborhoodVisible[i] == false) { AddDataBrowserItems(gDataBrowserControl, parentID, 1, &neighborhoodID, kNameColumn); if (gNeighborhoodInfo.isNeighborhoodOpen[i]) { OpenDataBrowserContainer(gDataBrowserControl, neighborhoodID); } } else { if (gNeighborhoodInfo.isNeighborhoodOpen[i]) { CancelServicesLookup(parentID); CancelNeighborhoodLookup(parentID); InstallEventLoopTimer(GetMainEventLoop(), 0.3, 0, gMyStartLookupTimerUPP, (void *)(neighborhoodID), NULL); } } } } CFRelease(tempNeighborhood); } free(neighborhood); } }