Commit e6f0a0f2 by O'Reilly Media, Inc.

Initial commit

parents
9780596101008
\ No newline at end of file
all: cf3 cf4 cf5 cf6
cf3: test8.o test3.o
cc -framework CoreFoundation $+ -o $@
cf4: test8.o test4.o
cc -framework CoreFoundation $+ -o $@
cf5: test8.o test5.o
cc -framework CoreFoundation $+ -o $@
cf6: test8.o test6.o
cc -framework CoreFoundation $+ -o $@
#include "stdafx.h" #include <dns_sd.h> #include <winsock2.h> #define WM_PRIVATE_SERVICE_EVENT ( WM_USER + 0x100 ) class MyWindow : public CWnd { public: MyWindow(); virtual ~MyWindow( void ); protected: // General afx_msg int OnCreate( LPCREATESTRUCT inCreateStruct ); afx_msg void OnDestroy( void ); afx_msg LONG OnServiceEvent( WPARAM inWParam, LPARAM inLParam ); // Browsing static void DNSSD_API BrowseReply( DNSServiceRef inRef, DNSServiceFlags inFlags, uint32_t inInterfaceIndex, DNSServiceErrorType inErrorCode, const char * inName, const char * inType, const char * inDomain, void * inContext ); DECLARE_MESSAGE_MAP() private: DNSServiceRef m_serviceRef; }; BEGIN_MESSAGE_MAP( MyWindow, CWnd ) ON_WM_CREATE() ON_WM_DESTROY() ON_MESSAGE( WM_PRIVATE_SERVICE_EVENT, OnServiceEvent ) END_MESSAGE_MAP() int MyWindow::OnCreate( LPCREATESTRUCT inCreateStruct ) { DNSServiceErrorType err; err = CWnd::OnCreate( inCreateStruct ); if ( err ) goto exit; err = DNSServiceBrowse( &m_serviceRef, 0, 0, "_http._tcp", NULL, BrowseReply, this ); if ( err ) goto exit; err = WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD(m_serviceRef), m_hWnd, WM_PRIVATE_SERVICE_EVENT, FD_READ|FD_CLOSE); exit: if ( err ) { if ( m_serviceRef ) { DNSServiceRefDeallocate( m_serviceRef ); m_serviceRef = NULL; } } return( err ); } void MyWindow::OnDestroy( void ) { // ... if ( m_serviceRef ) { WSAAsyncSelect( ( SOCKET ) DNSServiceRefSockFD( m_serviceRef ), m_hWnd, 0, 0 ); DNSServiceRefDeallocate( m_serviceRef ); } // ... } LONG MyWindow::OnServiceEvent(WPARAM inWParam, LPARAM inLParam) { SOCKET sock = (SOCKET) inWParam; DNSServiceErrorType err; if ( WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam))) goto exit; ASSERT( ( SOCKET ) DNSServiceRefSockFD( m_serviceRef ) == sock ); err = DNSServiceProcessResult( m_serviceRef ); ASSERT( !err ); exit: return ( 0 ); } void DNSSD_API MyWindow::BrowseReply( DNSServiceRef inRef, DNSServiceFlags inFlags, uint32_t inInterfaceIndex, DNSServiceErrorType inErrorCode, const char * inName, const char * inType, const char * inDomain, void * inContext ) { MyWindow * self = reinterpret_cast<MyWindow*>( inContext ); ASSERT( self ); // ... }
\ No newline at end of file
// Skeleton of how to handle DNSServiceDiscovery events using a select() loop
#include "dns_sd.h"
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
#include <errno.h> // For errno, EINTR
#include <time.h>
#include <sys/time.h> // For struct timeval
#include <unistd.h> // For getopt() and optind
#include <arpa/inet.h> // For inet_addr()
int stopNow = 0;
DNSServiceErrorType err;
void HandleEvents(DNSServiceRef serviceRef)
{
int dns_sd_fd = DNSServiceRefSockFD(serviceRef);
int nfds = dns_sd_fd + 1;
fd_set readfds;
struct timeval tv;
// . . .
while (!stopNow)
{
// . . .
int result = select(nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv);
if (result > 0)
{
// . . .
if (FD_ISSET(dns_sd_fd, &readfds))
err = DNSServiceProcessResult(serviceRef);
if (err) stopNow = 1;
}
}
}
main()
{
DNSServiceRef ref;
HandleEvents(ref);
}
// Simple example (single event source only)
// of how to handle DNSServiceDiscovery events using a select() loop
#include <dns_sd.h>
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
#include <errno.h> // For errno, EINTR
#include <time.h>
#ifdef _WIN32
#include <process.h>
typedef int pid_t;
#define getpid _getpid
#define strcasecmp _stricmp
#define snprintf _snprintf
#else
#include <sys/time.h> // For struct timeval
#include <unistd.h> // For getopt() and optind
#include <arpa/inet.h> // For inet_addr()
#endif
// Note: the select() implementation on Windows (Winsock2)
//fails with any timeout much larger than this
#define LONG_TIME 100000000
static volatile int stopNow = 0;
static volatile int timeOut = LONG_TIME;
void HandleEvents(DNSServiceRef serviceRef)
{
int dns_sd_fd = DNSServiceRefSockFD(serviceRef);
int nfds = dns_sd_fd + 1;
fd_set readfds;
struct timeval tv;
int result;
while (!stopNow)
{
FD_ZERO(&readfds);
FD_SET(dns_sd_fd, &readfds);
tv.tv_sec = timeOut;
tv.tv_usec = 0;
result = select(nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv);
if (result > 0)
{
DNSServiceErrorType err = kDNSServiceErr_NoError;
if (FD_ISSET(dns_sd_fd, &readfds))
err = DNSServiceProcessResult(serviceRef);
if (err) { fprintf(stderr,
"DNSServiceProcessResult returned %d\n", err);
stopNow = 1; }
}
else
{
printf("select() returned %d errno %d %s\n",
result, errno, strerror(errno));
if (errno != EINTR) stopNow = 1;
}
}
}
#include <dns_sd.h>
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
extern void HandleEvents(DNSServiceRef);
static void
MyBrowseCallBack(DNSServiceRef service,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char * name,
const char * type,
const char * domain,
void * context)
{
#pragma unused(context)
if (errorCode != kDNSServiceErr_NoError)
fprintf(stderr, "MyBrowseCallBack returned %d\n", errorCode);
else
{
char *addString = (flags & kDNSServiceFlagsAdd) ? "ADD" : "REMOVE";
char *moreString = (flags & kDNSServiceFlagsMoreComing) ? "MORE" : " ";
printf("%-7s%-5s %d%s.%s%s\n",
addString, moreString, interfaceIndex, name, type, domain);
}
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
static DNSServiceErrorType
MyDNSServiceBrowse()
{
DNSServiceErrorType error;
DNSServiceRef serviceRef;
error = DNSServiceBrowse(&serviceRef,
0, // no flags
0, // all network interfaces
"_http._tcp", // service type
"", // default domains
MyBrowseCallBack, // call back function
NULL); // no context
if (error == kDNSServiceErr_NoError)
{
HandleEvents(serviceRef); // Add service to runloop to get callbacks
DNSServiceRefDeallocate(serviceRef);
}
return error;
}
int main (int argc, const char * argv[])
{
DNSServiceErrorType error = MyDNSServiceBrowse();
if (error) fprintf(stderr, "DNSServiceDiscovery returned %d\n", error);
return 0;
}
// DNSServiceResolve example
#include <dns_sd.h>
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
extern void HandleEvents(DNSServiceRef);
static void
MyResolveCallBack(DNSServiceRef serviceRef,
DNSServiceFlags flags,
uint32_t interface,
DNSServiceErrorType errorCode,
const char *fullname,
const char *hosttarget,
uint16_t port,
uint16_t txtLen,
const char *txtRecord,
void *context)
{
#pragma unused(flags)
#pragma unused(fullname)
if (errorCode != kDNSServiceErr_NoError)
fprintf(stderr, "MyResolveCallBack returned %d\n", errorCode);
else
printf("RESOLVE: %s is at %s:%d\n", fullname, hosttarget, ntohs(port));
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
static DNSServiceErrorType MyDNSServiceResolve()
{
DNSServiceErrorType error;
DNSServiceRef serviceRef;
error = DNSServiceResolve(&serviceRef,
0, // no flags
0, // all network interfaces
"Not a real page", //name
"_http._tcp", // service type
"local", //domain
MyResolveCallBack,
NULL); // no context
if (error == kDNSServiceErr_NoError)
{
HandleEvents(serviceRef); // Add service to runloop to get callbacks
DNSServiceRefDeallocate(serviceRef);
}
return error;
}
int main (int argc, const char * argv[])
{
DNSServiceErrorType error = MyDNSServiceResolve();
fprintf(stderr, "DNSServiceDiscovery returned %d\n", error);
//if function returns print error
return 0;
}
// DNSServiceRegister example
#include <dns_sd.h>
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
extern void HandleEvents(DNSServiceRef);
static void
MyRegisterCallBack(DNSServiceRef service,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
const char * name,
const char * type,
const char * domain,
void * context)
{
#pragma unused(flags)
#pragma unused(context)
if (errorCode != kDNSServiceErr_NoError)
fprintf(stderr, "MyRegisterCallBack returned %d\n", errorCode);
else
printf("%-15s %s.%s%s\n","REGISTER", name, type, domain);
}
static DNSServiceErrorType MyDNSServiceRegister()
{
DNSServiceErrorType error;
DNSServiceRef serviceRef;
error = DNSServiceRegister(&serviceRef,
0, // no flags
0, // all network interfaces
"Not a real page", // name
"_http._tcp", // service type
"", // register in default domain(s)
NULL, // use default host name
htons(9092), // port number
0, // length of TXT record
NULL, // no TXT record
MyRegisterCallBack, // call back function
NULL); // no context
if (error == kDNSServiceErr_NoError)
{
HandleEvents(serviceRef);
DNSServiceRefDeallocate(serviceRef);
}
return error;
}
int main (int argc, const char * argv[])
{
DNSServiceErrorType error = MyDNSServiceRegister();
fprintf(stderr, "DNSServiceDiscovery returned %d\n", error);
return 0;
}
// DNSServiceEnumerateDomains example
#include <dns_sd.h>
#include <stdio.h> // For stdout, stderr
#include <string.h> // For strlen(), strcpy(), bzero()
extern void HandleEvents(DNSServiceRef);
static void
MyEnumerateBrowseDomainsCallBack(DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interface,
DNSServiceErrorType errorCode,
const char *replyDomain,
void *context)
{
#pragma unused(context)
if (errorCode != kDNSServiceErr_NoError)
fprintf(stderr, "MyEnumerateBrowseDomainsCallBack returned %d\n", errorCode);
else
{
char *moreString = (flags & kDNSServiceFlagsMoreComing) ? "MORE" : "";
char *addString = "REMOVE";
if (flags & kDNSServiceFlagsAdd)
addString = (flags & kDNSServiceFlagsDefault) ? "DEFAULT" : "ADD";
printf("%-8s%-5s%s\n", addString, moreString, replyDomain);
}
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
static DNSServiceErrorType MyDNSServiceEnumerateBrowse()
{
DNSServiceErrorType error;
DNSServiceRef serviceRef;
error = DNSServiceEnumerateDomains(
&serviceRef,
kDNSServiceFlagsBrowseDomains, // browse domains
0, // all network interfaces
MyEnumerateBrowseDomainsCallBack, //callback function
NULL); // no context
if (error == kDNSServiceErr_NoError)
{
HandleEvents(serviceRef); // Add service to runloop to get callbacks
DNSServiceRefDeallocate(serviceRef);
}
return error;
}
int main (int argc, const char * argv[])
{
DNSServiceErrorType error = MyDNSServiceEnumerateBrowse();
if (error) fprintf(stderr, "DNSServiceDiscovery returned %d\n", error);
return 0;
}
// Skeleton of how to handle DNSServiceDiscovery events using a CFRunLoop
typedef struct MyDNSServiceState
{
DNSServiceRef service;
CFSocketRef socket;
CFRunLoopSourceRef source;
} MyDNSServiceState;
void HandleEvents(DNSServiceRef serviceRef)
{
// . . .
// Access the underlying Unix domain socket and create a CFSocket
sock = DNSServiceRefSockFD(ref->service);
ref->socket = CFSocketCreateWithNative(NULL, sock,
kCFSocketReadCallBack,
MySocketCallBack, &context);
// . . .
// Create a CFRunLoopSource from the CFSocket, add to run loop and start.
ref->source = CFSocketCreateRunLoopSource(NULL, ref->socket, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), ref->source, kCFRunLoopCommonModes);
CFRunLoopRun();
}
// Simple example of how to handle DNSServiceDiscovery events using a CFRunLoop
#include <dns_sd.h>
#include <CoreFoundation/CoreFoundation.h>
// Structure to hold CFRunLoop-related state
typedef struct MyDNSServiceState
{
DNSServiceRef service; // Active DNSServiceDiscovery operation
CFSocketRef cfsocket; // CFSocket for this operation
CFRunLoopSourceRef source; // RunLoopSource for this CFSocket
} MyDNSServiceState;
// Remove a DNSServiceDiscovery operation from a CFRunLoop's
// set of active event sources
static void DNSServiceRemoveSource(CFRunLoopRef rl, MyDNSServiceState *ref)
{
assert(rl != NULL);
assert(ref != NULL);
// Remove the CFRunLoopSource from the current run loop.
CFRunLoopRemoveSource(rl, ref->source, kCFRunLoopCommonModes);
CFRelease(ref->source);
// Invalidate the CFSocket.
CFSocketInvalidate(ref->cfsocket);
CFRelease(ref->cfsocket);
// Workaround to give time to CFSocket's select() thread
// so it can remove the socket from its FD set before we
// close the socket by calling DNSServiceRefDeallocate.
usleep(1000);
// Terminate the connection with the daemon, which cancels the operation.
DNSServiceRefDeallocate(ref->service);
free(ref);
}
// Helper function: When CFRunLoop indicates an interesting event,
// this function calls DNSServiceProcessResult() to handle it
static void MySocketCallBack(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 *ref = (MyDNSServiceState *)info;
assert(ref != NULL);
// Read a reply from the daemon, which will call the appropriate callback.
err= DNSServiceProcessResult(ref->service);
if (err != kDNSServiceErr_NoError)
{
fprintf(stderr, "DNSServiceProcessResult returned %d\n", err);
// Terminate the discovery operation and release everything.
DNSServiceRemoveSource(CFRunLoopGetCurrent(), ref);
}
}
// Add a DNSServiceDiscovery operation to a CFRunLoop's
// set of active event sources
static void DNSServiceAddSource(CFRunLoopRef rl, MyDNSServiceState *ref)
{
CFSocketContext context = { 0, ref, NULL, NULL, NULL };
CFSocketNativeHandle sock = DNSServiceRefSockFD(ref->service);
assert(sock != -1);
// Create a CFSocket from the underlying Unix Domain socket.
ref->cfsocket = CFSocketCreateWithNative(NULL, sock,
kCFSocketReadCallBack, MySocketCallBack, &context);
// Prevent CFSocketInvalidate from closing DNSServiceRef's socket.
CFOptionFlags f = CFSocketGetSocketFlags(ref->cfsocket);
CFSocketSetSocketFlags(ref->cfsocket, f & ~kCFSocketCloseOnInvalidate);
// Create a CFRunLoopSource from the CFSocket.
ref->source = CFSocketCreateRunLoopSource(NULL, ref->cfsocket, 0);
// Add the CFRunLoopSource to the current run loop.
CFRunLoopAddSource(rl, ref->source, kCFRunLoopCommonModes);
}
// Simple example: Here we just add a single DNSServiceDiscovery event source,
// and then call CFRunLoopRun() to handle the events. In a program that already
// has a main RunLoop, you'd just keep that as is, and use DNSServiceAddSource/
// DNSServiceRemoveSource to add and remove event sources from that RunLoop.
void HandleEvents(DNSServiceRef serviceRef)
{
MyDNSServiceState ref = { serviceRef };
DNSServiceAddSource(CFRunLoopGetCurrent(), &ref);
CFRunLoopRun();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ActivePerspectiveName</key>
<string>Project</string>
<key>AllowedModules</key>
<array>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
<key>Name</key>
<string>Groups and Files Outline View</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Name</key>
<string>Editor</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCTaskListModule</string>
<key>Name</key>
<string>Task List</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCDetailModule</string>
<key>Name</key>
<string>File and Smart Group Detail Viewer</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXBuildResultsModule</string>
<key>Name</key>
<string>Detailed Build Results Viewer</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXProjectFindModule</string>
<key>Name</key>
<string>Project Batch Find Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXRunSessionModule</string>
<key>Name</key>
<string>Run Log</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXBookmarksModule</string>
<key>Name</key>
<string>Bookmarks Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXClassBrowserModule</string>
<key>Name</key>
<string>Class Browser</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXCVSModule</string>
<key>Name</key>
<string>Source Code Control Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXDebugBreakpointsModule</string>
<key>Name</key>
<string>Debug Breakpoints Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCDockableInspector</string>
<key>Name</key>
<string>Inspector</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>