-static void ServiceDomainEnumReply( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *replyDomain, void *context, DNSServiceFlags enumType)
-{
- (void)sdRef; // Unused
- (void)interfaceIndex; // Unused
- (void)errorCode; // Unused
- if (strcmp(replyDomain, "local.") == 0) return; // local domain is not interesting
-
- DNSServiceDiscoveryPref * me = (DNSServiceDiscoveryPref *)context;
- BOOL moreComing = (BOOL)(flags & kDNSServiceFlagsMoreComing);
- NSMutableArray * domainArray;
- NSMutableArray * defaultBrowseDomainsArray = nil;
- NSComboBox * domainComboBox;
- NSString * domainString;
- NSString * currentDomain = nil;
- char decodedDomainString[kDNSServiceMaxDomainName] = "\0";
- char nextLabel[256] = "\0";
- char * buffer = (char *)replyDomain;
-
- while (*buffer) {
- buffer = (char *)GetNextLabel(buffer, nextLabel);
- strcat(decodedDomainString, nextLabel);
- strcat(decodedDomainString, ".");
- }
-
- // Remove trailing dot from domain name.
- decodedDomainString[strlen(decodedDomainString)-1] = '\0';
-
- domainString = [[[NSString alloc] initWithUTF8String:(const char *)decodedDomainString] autorelease];
-
- if (enumType & kDNSServiceFlagsRegistrationDomains) {
- domainArray = [me registrationDataSource];
- domainComboBox = [me regDomainsComboBox];
- currentDomain = [me currentRegDomain];
- } else {
- domainArray = [me browseDataSource];
- domainComboBox = [me browseDomainsComboBox];
- defaultBrowseDomainsArray = [me defaultBrowseDomainsArray];
- }
-
- if (flags & kDNSServiceFlagsAdd) {
- [domainArray removeObject:domainString]; // How can I check if an object is in the array?
- [domainArray addObject:domainString];
- if ((flags & kDNSServiceFlagsDefault) && (enumType & kDNSServiceFlagsRegistrationDomains)) {
- [me setDefaultRegDomain:domainString];
- if ([[domainComboBox stringValue] length] == 0) [domainComboBox setStringValue:domainString];
- } else if ((flags & kDNSServiceFlagsDefault) && !(enumType & kDNSServiceFlagsRegistrationDomains)) {
- [defaultBrowseDomainsArray removeObject:domainString];
- [defaultBrowseDomainsArray addObject:domainString];
- }
- }
-
- if (moreComing == NO) {
- [domainArray sortUsingFunction:MyArrayCompareFunction context:nil];
- [domainComboBox reloadData];
- }
-}
-
-
-static void
-browseDomainReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *replyDomain, void *context)
-{
- ServiceDomainEnumReply(sdRef, flags, interfaceIndex, errorCode, replyDomain, context, kDNSServiceFlagsBrowseDomains);
-}
-
-
-static void
-registrationDomainReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *replyDomain, void *context)
-{
- ServiceDomainEnumReply(sdRef, flags, interfaceIndex, errorCode, replyDomain, context, kDNSServiceFlagsRegistrationDomains);
-}
-
-
-
-static void
-MyDNSServiceCleanUp(MyDNSServiceState * query)
-{
- /* Remove the CFRunLoopSource from the current run loop. */
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), query->source, kCFRunLoopCommonModes);
- CFRelease(query->source);
-
- /* Invalidate the CFSocket. */
- CFSocketInvalidate(query->socket);
- CFRelease(query->socket);
-
- /* Workaround that gives time to CFSocket's select thread so it can remove the socket from its FD set
- before we close the socket by calling DNSServiceRefDeallocate. <rdar://problem/3585273> */
- usleep(1000);
-
- /* Terminate the connection with the mDNSResponder daemon, which cancels the query. */
- DNSServiceRefDeallocate(query->service);
-}
-
-
-
-static void
-MySocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void * data, void * info)
-{
- #pragma unused(s)
- #pragma unused(type)
- #pragma unused(address)
- #pragma unused(data)
-
- DNSServiceErrorType err;
-
- MyDNSServiceState * query = (MyDNSServiceState *)info; // context passed in to CFSocketCreateWithNative().
- assert(query != NULL);
-
- /* Read a reply from the mDNSResponder. */
- err= DNSServiceProcessResult(query->service);
- if (err != kDNSServiceErr_NoError) {
- fprintf(stderr, "DNSServiceProcessResult returned %d\n", err);
-
- /* Terminate the query operation and release the CFRunLoopSource and CFSocket. */
- MyDNSServiceCleanUp(query);
- }
-}
-
-
-
-static void
-MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
-{
- CFSocketNativeHandle sock;
- CFOptionFlags sockFlags;
- CFSocketContext context = { 0, query, NULL, NULL, NULL }; // Use MyDNSServiceState as context data.
-
- /* Access the underlying Unix domain socket to communicate with the mDNSResponder daemon. */
- sock = DNSServiceRefSockFD(query->service);
- assert(sock != -1);
-
- /* Create a CFSocket using the Unix domain socket. */
- query->socket = CFSocketCreateWithNative(NULL, sock, kCFSocketReadCallBack, MySocketReadCallback, &context);
- assert(query->socket != NULL);
-
- /* Prevent CFSocketInvalidate from closing DNSServiceRef's socket. */
- sockFlags = CFSocketGetSocketFlags(query->socket);
- CFSocketSetSocketFlags(query->socket, sockFlags & (~kCFSocketCloseOnInvalidate));
-
- /* Create a CFRunLoopSource from the CFSocket. */
- query->source = CFSocketCreateRunLoopSource(NULL, query->socket, 0);
- assert(query->source != NULL);
-
- /* Add the CFRunLoopSource to the current run loop. */
- CFRunLoopAddSource(CFRunLoopGetCurrent(), query->source, kCFRunLoopCommonModes);
-}
-
-
-