/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.

    Change History (most recent first):

$Log: DNSServiceBrowser.m,v $
Revision 1.35  2006/11/27 08:27:49  mkrochma
Fix a crashing bug

Revision 1.34  2006/11/24 05:41:07  mkrochma
More cleanup and more service types

Revision 1.33  2006/11/24 01:34:24  mkrochma
Display interface index and query for IPv6 addresses even when there's no IPv4

Revision 1.32  2006/11/24 00:25:31  mkrochma
<rdar://problem/4084652> Tools: DNS Service Browser contains some bugs

Revision 1.31  2006/08/14 23:23:55  cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0

Revision 1.30  2005/01/27 17:46:16  cheshire
Added comment

Revision 1.29  2004/06/04 20:58:36  cheshire
Move DNSServiceBrowser from mDNSMacOSX directory to Clients directory

Revision 1.28  2004/05/18 23:51:26  cheshire
Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers

Revision 1.27  2003/11/19 18:49:48  rpantos
<rdar://problem/3282283> couple of little tweaks to previous checkin

Revision 1.26  2003/11/07 19:35:20  rpantos
<rdar://problem/3282283> Display multiple IP addresses. Connect using host rather than IP addr.

Revision 1.25  2003/10/29 05:16:54  rpantos
Checkpoint: transition from DNSServiceDiscovery.h to dns_sd.h

Revision 1.24  2003/10/28 02:25:45  rpantos
<rdar://problem/3282283> Cancel pending resolve when focus changes or service disappears.

Revision 1.23  2003/10/28 01:29:15  rpantos
<rdar://problem/3282283> Restructure a bit to make arrow keys work & views behave better.

Revision 1.22  2003/10/28 01:23:27  rpantos
<rdar://problem/3282283> Bail if mDNS cannot be initialized at startup.

Revision 1.21  2003/10/28 01:19:45  rpantos
<rdar://problem/3282283> Do not put a trailing '.' on service names. Handle PATH for HTTP txtRecords.

Revision 1.20  2003/10/28 01:13:49  rpantos
<rdar://problem/3282283> Remove filter when displaying browse results.

Revision 1.19  2003/10/28 01:10:14  rpantos
<rdar://problem/3282283> Change 'compare' to 'caseInsensitiveCompare' to fix sort order.

Revision 1.18  2003/08/12 19:55:07  cheshire
Update to APSL 2.0

*/

#import <Cocoa/Cocoa.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <unistd.h>
#include <dns_sd.h>

@class ServiceController;  // holds state corresponding to outstanding DNSServiceRef

@interface BrowserController : NSObject
{
    IBOutlet id nameField;
    IBOutlet id typeField;

    IBOutlet id serviceDisplayTable;
    IBOutlet id typeColumn;
    IBOutlet id nameColumn;
    IBOutlet id serviceTypeField;
    IBOutlet id serviceNameField;

    IBOutlet id hostField;
    IBOutlet id ipAddressField;
    IBOutlet id ip6AddressField;
    IBOutlet id portField;
    IBOutlet id interfaceField;
    IBOutlet id textField;
    
    NSMutableArray *_srvtypeKeys;
    NSMutableArray *_srvnameKeys;
    NSMutableArray *_sortedServices;
    NSMutableDictionary *_servicesDict;

	ServiceController *_serviceBrowser;
	ServiceController *_serviceResolver;
	ServiceController *_ipv4AddressResolver;
	ServiceController *_ipv6AddressResolver;
}

- (void)notifyTypeSelectionChange:(NSNotification*)note;
- (void)notifyNameSelectionChange:(NSNotification*)note;

- (IBAction)connect:(id)sender;

- (IBAction)handleTableClick:(id)sender;
- (IBAction)removeSelected:(id)sender;
- (IBAction)addNewService:(id)sender;

- (IBAction)update:(NSString *)Type;

- (void)updateBrowseWithName:(const char *)name type:(const char *)resulttype domain:(const char *)domain interface:(uint32_t)interface flags:(DNSServiceFlags)flags;
- (void)resolveClientWitHost:(NSString *)host port:(uint16_t)port interfaceIndex:(uint32_t)interface txtRecord:(const char*)txtRecord txtLen:(uint16_t)txtLen;
- (void)updateAddress:(uint16_t)rrtype addr:(const void *)buff addrLen:(uint16_t)addrLen host:(const char*)host interfaceIndex:(uint32_t)interface more:(boolean_t)moreToCome;

- (void)_cancelPendingResolve;
- (void)_clearResolvedInfo;

@end

// The ServiceController manages cleanup of DNSServiceRef & runloop info for an outstanding request
@interface ServiceController : NSObject
{
	DNSServiceRef       fServiceRef;
	CFSocketRef         fSocketRef;
	CFRunLoopSourceRef  fRunloopSrc;
}

- (id)initWithServiceRef:(DNSServiceRef)ref;
- (void)addToCurrentRunLoop;
- (DNSServiceRef)serviceRef;
- (void)dealloc;

@end // interface ServiceController


static void
ProcessSockData(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
	DNSServiceRef serviceRef = (DNSServiceRef)info;
	DNSServiceErrorType err = DNSServiceProcessResult(serviceRef);
	if (err != kDNSServiceErr_NoError) {
		printf("DNSServiceProcessResult() returned an error! %d\n", err);
    }
}


static void
ServiceBrowseReply(DNSServiceRef sdRef, DNSServiceFlags servFlags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, 
    const char *serviceName, const char *regtype, const char *replyDomain, void *context)
{
	if (errorCode == kDNSServiceErr_NoError) {
		[(BrowserController*)context updateBrowseWithName:serviceName type:regtype domain:replyDomain interface:interfaceIndex flags:servFlags];
	} else {
		printf("ServiceBrowseReply got an error! %d\n", errorCode);
	}
}


static void
ServiceResolveReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode,
    const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const char *txtRecord, void *context)
{
	if (errorCode == kDNSServiceErr_NoError) {
		[(BrowserController*)context resolveClientWitHost:[NSString stringWithUTF8String:hosttarget] port:port interfaceIndex:interfaceIndex txtRecord:txtRecord txtLen:txtLen];
	} else {
		printf("ServiceResolveReply got an error! %d\n", errorCode);
	}
}


static void
QueryRecordReply(DNSServiceRef DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode,
    const char *fullname, uint16_t rrtype, uint16_t rrclass,  uint16_t rdlen, const void *rdata, uint32_t ttl, void *context)
{
    if (errorCode == kDNSServiceErr_NoError) {
        [(BrowserController*)context updateAddress:rrtype addr:rdata addrLen:rdlen host:fullname interfaceIndex:interfaceIndex more:(flags & kDNSServiceFlagsMoreComing)];
    } else {
        printf("QueryRecordReply got an error! %d\n", errorCode);
    }
}


static void
InterfaceIndexToName(uint32_t interface, char *interfaceName)
{
    assert(interfaceName);
    
    if (interface == kDNSServiceInterfaceIndexAny) {
        // All active network interfaces.
        strlcpy(interfaceName, "all", IF_NAMESIZE);
    } else if (interface == kDNSServiceInterfaceIndexLocalOnly) {
        // Only available locally on this machine.
        strlcpy(interfaceName, "local", IF_NAMESIZE);
    } else {
        // Converts interface index to interface name.
        if_indextoname(interface, interfaceName);
    }
}


@implementation BrowserController		//Begin implementation of BrowserController methods

- (void)registerDefaults
{
    NSMutableDictionary *regDict = [NSMutableDictionary dictionary];

    NSArray *typeArray = [NSArray arrayWithObjects:@"_afpovertcp._tcp",
                                                   @"_smb._tcp",
                                                   @"_rfb._tcp",
												   @"_ssh._tcp",
                                                   @"_ftp._tcp",
												   @"_http._tcp",
												   @"_printer._tcp",
                                                   @"_ipp._tcp",
                                                   @"_airport._tcp",
												   @"_presence._tcp",
												   @"_daap._tcp",
												   @"_dpap._tcp",
                                                   nil];
                                                   
    NSArray *nameArray = [NSArray arrayWithObjects:@"AppleShare Servers",
                                                   @"Windows Sharing",
                                                   @"Screen Sharing",
	                                               @"Secure Shell",
                                                   @"FTP Servers",
	                                               @"Web Servers",
	                                               @"LPR Printers",
                                                   @"IPP Printers",
                                                   @"AirPort Base Stations",
												   @"iChat Buddies",
												   @"iTunes Libraries",
												   @"iPhoto Libraries",
                                                   nil];

    [regDict setObject:typeArray forKey:@"SrvTypeKeys"];
    [regDict setObject:nameArray forKey:@"SrvNameKeys"];

    [[NSUserDefaults standardUserDefaults] registerDefaults:regDict];
}


- (id)init
{
    self = [super init];
    if (self) {
        _srvtypeKeys = nil;
        _srvnameKeys = nil;
        _serviceBrowser = nil;
        _serviceResolver = nil;
        _ipv4AddressResolver = nil;
        _ipv6AddressResolver = nil;
        _sortedServices = [[NSMutableArray alloc] init];
        _servicesDict = [[NSMutableDictionary alloc] init];
    }
    return self;
}


- (void)awakeFromNib
{
    [typeField sizeLastColumnToFit];
    [nameField sizeLastColumnToFit];
    [nameField setDoubleAction:@selector(connect:)];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyTypeSelectionChange:) name:NSTableViewSelectionDidChangeNotification object:typeField];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyNameSelectionChange:) name:NSTableViewSelectionDidChangeNotification object:nameField];
    
    _srvtypeKeys = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTypeKeys"] mutableCopy];
    _srvnameKeys = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvNameKeys"] mutableCopy];

    if (!_srvtypeKeys || !_srvnameKeys) {
        [_srvtypeKeys release];
        [_srvnameKeys release];
        [self registerDefaults];
        _srvtypeKeys = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTypeKeys"] mutableCopy];
        _srvnameKeys = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvNameKeys"] mutableCopy];
    }
    
    [typeField reloadData];
}


- (void)dealloc
{
    [_srvtypeKeys release];
    [_srvnameKeys release];
    [_servicesDict release];
    [_sortedServices release];
    [super dealloc];
}


-(void)tableView:(NSTableView *)theTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
    if (row < 0) return;
}


- (int)numberOfRowsInTableView:(NSTableView *)theTableView	//Begin mandatory TableView methods
{
    if (theTableView == typeField) {
        return [_srvnameKeys count];
    }
    if (theTableView == nameField) {
        return [_servicesDict count];
    }
    if (theTableView == serviceDisplayTable) {
        return [_srvnameKeys count];
    }
    return 0;
}


- (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)theColumn row:(int)rowIndex
{
    if (theTableView == typeField) {
        return [_srvnameKeys objectAtIndex:rowIndex];
    }
    if (theTableView == nameField) {
        return [[_servicesDict objectForKey:[_sortedServices objectAtIndex:rowIndex]] name];
    }
    if (theTableView == serviceDisplayTable) {
        if (theColumn == typeColumn) {
            return [_srvtypeKeys objectAtIndex:rowIndex];
        }
        if (theColumn == nameColumn) {
            return [_srvnameKeys objectAtIndex:rowIndex];
        }
        return nil;
    }
    
    return nil;
}


- (void)notifyTypeSelectionChange:(NSNotification*)note
{
    [self _cancelPendingResolve];

    int index = [[note object] selectedRow];
    if (index != -1) {
        [self update:[_srvtypeKeys objectAtIndex:index]];
    } else {
        [self update:nil];
    }
}


- (void)notifyNameSelectionChange:(NSNotification*)note
{
    [self _cancelPendingResolve];
    
    int index = [[note object] selectedRow];
    if (index == -1) {
		return;
	}
    
    // Get the currently selected service
    NSNetService *service = [_servicesDict objectForKey:[_sortedServices objectAtIndex:index]];
	
    DNSServiceRef serviceRef;
	DNSServiceErrorType err = DNSServiceResolve(&serviceRef,
                                         (DNSServiceFlags)0,
                               kDNSServiceInterfaceIndexAny,
                  (const char *)[[service name] UTF8String],
                 (const char *)[[service type]  UTF8String],
                (const char *)[[service domain] UTF8String],
                (DNSServiceResolveReply)ServiceResolveReply,
                                                      self);
        
	if (kDNSServiceErr_NoError == err) {
		_serviceResolver = [[ServiceController alloc] initWithServiceRef:serviceRef];
		[_serviceResolver addToCurrentRunLoop];
	}
}


- (IBAction)update:(NSString *)theType
{
    [_servicesDict removeAllObjects];
    [_sortedServices removeAllObjects];
    [nameField reloadData];

    // get rid of the previous browser if one exists
    if (_serviceBrowser != nil) {
		[_serviceBrowser release];
        _serviceBrowser = nil;
    }
    
    if (theType) {
        DNSServiceRef serviceRef;
        DNSServiceErrorType err = DNSServiceBrowse(&serviceRef, (DNSServiceFlags)0, 0, [theType UTF8String], NULL, ServiceBrowseReply, self);
        if (kDNSServiceErr_NoError == err) {
            _serviceBrowser = [[ServiceController alloc] initWithServiceRef:serviceRef];
            [_serviceBrowser addToCurrentRunLoop];
        }
    }
}


- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
    return YES;
}


- (void)updateBrowseWithName:(const char *)name type:(const char *)type domain:(const char *)domain interface:(uint32_t)interface flags:(DNSServiceFlags)flags
{
    NSString *key = [NSString stringWithFormat:@"%s.%s%s%d", name, type, domain, interface];
    NSNetService *service = [[NSNetService alloc] initWithDomain:[NSString stringWithUTF8String:domain] type:[NSString stringWithUTF8String:type] name:[NSString stringWithUTF8String:name]];
    
    if (flags & kDNSServiceFlagsAdd) {
        [_servicesDict setObject:service forKey:key];
    } else {
        [_servicesDict removeObjectForKey:key];
    }

    // If not expecting any more data, then reload (redraw) TableView with newly found data
    if (!(flags & kDNSServiceFlagsMoreComing)) {
    
        // Save the current TableView selection
        int index = [nameField selectedRow];
        NSString *selected = (index != -1) ? [[_sortedServices objectAtIndex:index] copy] : nil;
        
        [_sortedServices release];
        _sortedServices = [[_servicesDict allKeys] mutableCopy];        
        [_sortedServices sortUsingSelector:@selector(caseInsensitiveCompare:)];
        [nameField reloadData];
        
        // Restore the previous TableView selection
        index = selected ? [_sortedServices indexOfObject:selected] : NSNotFound;
        if (index != NSNotFound) {
            [nameField selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
            [nameField scrollRowToVisible:index];
        }
        
        [selected release];
    }

    [service release];

    return;
}


- (void)resolveClientWitHost:(NSString *)host port:(uint16_t)port interfaceIndex:(uint32_t)interface txtRecord:(const char*)txtRecord txtLen:(uint16_t)txtLen
{
	DNSServiceRef serviceRef;

	if (_ipv4AddressResolver) {
		[_ipv4AddressResolver release];
		_ipv4AddressResolver = nil;
	}
    
    if (_ipv6AddressResolver) {
		[_ipv6AddressResolver release];
		_ipv6AddressResolver = nil;
	}

	// Start an async lookup for IPv4 addresses
	DNSServiceErrorType err = DNSServiceQueryRecord(&serviceRef, (DNSServiceFlags)0, interface, [host UTF8String], kDNSServiceType_A, kDNSServiceClass_IN, QueryRecordReply, self);
	if (err == kDNSServiceErr_NoError) {
		_ipv4AddressResolver = [[ServiceController alloc] initWithServiceRef:serviceRef];
		[_ipv4AddressResolver addToCurrentRunLoop];
	}

	// Start an async lookup for IPv6 addresses
    err = DNSServiceQueryRecord(&serviceRef, (DNSServiceFlags)0, interface, [host UTF8String], kDNSServiceType_AAAA, kDNSServiceClass_IN, QueryRecordReply, self);
    if (err == kDNSServiceErr_NoError) {
        _ipv6AddressResolver = [[ServiceController alloc] initWithServiceRef:serviceRef];
        [_ipv6AddressResolver addToCurrentRunLoop];
    }

    char interfaceName[IF_NAMESIZE];
    InterfaceIndexToName(interface, interfaceName);

    [hostField setStringValue:host];
    [interfaceField setStringValue:[NSString stringWithUTF8String:interfaceName]];
    [portField setIntValue:ntohs(port)];

	// kind of a hack: munge txtRecord so it's human-readable
	if (txtLen > 0) {
		char *readableText = (char*) malloc(txtLen);
		if (readableText != nil) {
			ByteCount index, subStrLen;
			memcpy(readableText, txtRecord, txtLen);
			for (index=0; index < txtLen - 1; index += subStrLen + 1) {
				subStrLen = readableText[index];
				readableText[index] = ' ';
			}
			[textField setStringValue:[NSString stringWithCString:&readableText[1] length:txtLen - 1]];
			free(readableText);
		}
	}
}


- (void)updateAddress:(uint16_t)rrtype  addr:(const void *)buff addrLen:(uint16_t)addrLen host:(const char*) host interfaceIndex:(uint32_t)interface more:(boolean_t)moreToCome
{
    char addrBuff[256];

	if (rrtype == kDNSServiceType_A) {
		inet_ntop(AF_INET, buff, addrBuff, sizeof(addrBuff));
        if ([[ipAddressField stringValue] length] > 0) {
            [ipAddressField setStringValue:[NSString stringWithFormat:@"%@, ", [ipAddressField stringValue]]];
        }
		[ipAddressField setStringValue:[NSString stringWithFormat:@"%@%s", [ipAddressField stringValue], addrBuff]];

		if (!moreToCome) {
			[_ipv4AddressResolver release];
			_ipv4AddressResolver = nil;
		}
	} else if (rrtype == kDNSServiceType_AAAA) {
		inet_ntop(AF_INET6, buff, addrBuff, sizeof(addrBuff));
        if ([[ip6AddressField stringValue] length] > 0) {
            [ip6AddressField setStringValue:[NSString stringWithFormat:@"%@, ", [ip6AddressField stringValue]]];
        }
		[ip6AddressField setStringValue:[NSString stringWithFormat:@"%@%s", [ip6AddressField stringValue], addrBuff]];

		if (!moreToCome) {
			[_ipv6AddressResolver release];
			_ipv6AddressResolver = nil;
		}
	}
}


- (void)connect:(id)sender
{
    NSString *host = [hostField stringValue];
    NSString *txtRecord = [textField stringValue];
    int port = [portField intValue];
        
    int index = [nameField selectedRow];
    NSString *selected = (index >= 0) ? [_sortedServices objectAtIndex:index] : nil;
    NSString *type = [[_servicesDict objectForKey:selected] type];
    
    if ([type isEqual:@"_http._tcp."]) {
        NSString *pathDelim = @"path=";
		NSRange where;

        // If the TXT record specifies a path, extract it.
		where = [txtRecord rangeOfString:pathDelim options:NSCaseInsensitiveSearch];
        if (where.length) {
			NSRange	targetRange = { where.location + where.length, [txtRecord length] - where.location - where.length };
			NSRange	endDelim = [txtRecord rangeOfString:@"\n" options:kNilOptions range:targetRange];
			
			if (endDelim.length)   // if a delimiter was found, truncate the target range
				targetRange.length = endDelim.location - targetRange.location;

            NSString    *path = [txtRecord substringWithRange:targetRange];
            [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%d%@", host, port, path]]];
        } else {
            [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%d", host, port]]];
        }
    }
    else if ([type isEqual:@"_ftp._tcp."])        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"ftp://%@:%d/", host, port]]];
    else if ([type isEqual:@"_ssh._tcp."])        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"ssh://%@:%d/", host, port]]];
    else if ([type isEqual:@"_afpovertcp._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"afp://%@:%d/", host, port]]];
    else if ([type isEqual:@"_smb._tcp."])        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"smb://%@:%d/", host, port]]];
    else if ([type isEqual:@"_rfb._tcp."])        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"vnc://%@:%d/", host, port]]];

    return;
}


- (IBAction)handleTableClick:(id)sender
{
    //populate the text fields
}


- (IBAction)removeSelected:(id)sender
{
    // remove the selected row and force a refresh

    int selectedRow = [serviceDisplayTable selectedRow];

    if (selectedRow) {

        [_srvtypeKeys removeObjectAtIndex:selectedRow];
        [_srvnameKeys removeObjectAtIndex:selectedRow];

        [[NSUserDefaults standardUserDefaults] setObject:_srvtypeKeys forKey:@"SrvTypeKeys"];
        [[NSUserDefaults standardUserDefaults] setObject:_srvnameKeys forKey:@"SrvNameKeys"];

        [typeField reloadData];
        [serviceDisplayTable reloadData];
    }
}


- (IBAction)addNewService:(id)sender
{
    // add new entries from the edit fields to the arrays for the defaults
    NSString *newType = [serviceTypeField stringValue];
    NSString *newName = [serviceNameField stringValue];

    // 3282283: trim trailing '.' from service type field
    if ([newType length] && [newType hasSuffix:@"."])
        newType = [newType substringToIndex:[newType length] - 1];

    if ([newType length] && [newName length]) {
        [_srvtypeKeys addObject:newType];
        [_srvnameKeys addObject:newName];

        [[NSUserDefaults standardUserDefaults] setObject:_srvtypeKeys forKey:@"SrvTypeKeys"];
        [[NSUserDefaults standardUserDefaults] setObject:_srvnameKeys forKey:@"SrvNameKeys"];

        [typeField reloadData];
        [serviceDisplayTable reloadData];
    }
}


- (void)_cancelPendingResolve
{
    [_ipv4AddressResolver release];
    _ipv4AddressResolver = nil;

    [_ipv6AddressResolver release];
    _ipv6AddressResolver = nil;

    [_serviceResolver release];
    _serviceResolver = nil;

	[self _clearResolvedInfo];
}


- (void)_clearResolvedInfo
{
	[hostField setStringValue:@""];
	[ipAddressField setStringValue:@""];
	[ip6AddressField setStringValue:@""];
	[portField setStringValue:@""];
    [interfaceField setStringValue:@""];
	[textField setStringValue:@""];
}

@end // implementation BrowserController


@implementation ServiceController : NSObject
{
	DNSServiceRef        fServiceRef;
	CFSocketRef          fSocketRef;
	CFRunLoopSourceRef   fRunloopSrc;
}


- (id)initWithServiceRef:(DNSServiceRef)ref
{
	self = [super init];
    if (self) {
        fServiceRef = ref;
        fSocketRef = NULL;
        fRunloopSrc = NULL;
    }
	return self;
}


- (void)addToCurrentRunLoop
{
	CFSocketContext	context = { 0, (void*)fServiceRef, NULL, NULL, NULL };

	fSocketRef = CFSocketCreateWithNative(kCFAllocatorDefault, DNSServiceRefSockFD(fServiceRef), kCFSocketReadCallBack, ProcessSockData, &context);
	if (fSocketRef) {
        // Prevent CFSocketInvalidate from closing DNSServiceRef's socket.
        CFOptionFlags sockFlags = CFSocketGetSocketFlags(fSocketRef);
        CFSocketSetSocketFlags(fSocketRef, sockFlags & (~kCFSocketCloseOnInvalidate));
		fRunloopSrc = CFSocketCreateRunLoopSource(kCFAllocatorDefault, fSocketRef, 0);
    }
	if (fRunloopSrc) {
		CFRunLoopAddSource(CFRunLoopGetCurrent(), fRunloopSrc, kCFRunLoopDefaultMode);
    } else {
		printf("Could not listen to runloop socket\n");
    }
}


- (DNSServiceRef)serviceRef
{
	return fServiceRef;
}


- (void)dealloc
{
	if (fSocketRef) {
		CFSocketInvalidate(fSocketRef);		// Note: Also closes the underlying socket
		CFRelease(fSocketRef);
        
        // 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);
	}

	if (fRunloopSrc) {
		CFRunLoopRemoveSource(CFRunLoopGetCurrent(), fRunloopSrc, kCFRunLoopDefaultMode);
		CFRelease(fRunloopSrc);
	}

	DNSServiceRefDeallocate(fServiceRef);

	[super dealloc];
}


@end // implementation ServiceController

int main(int argc, const char *argv[])
{
    return NSApplicationMain(argc, argv);
}
