#if defined(DARWIN)
#include <arpa/inet.h>
#include <dns_sd.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "config.h"
#include "distcc.h"
#include "dopt.h"
#include "trace.h"
#include "zeroconf_reg.h"
#include "zeroconf_util.h"
#define ZC_CONTEXT NULL
#define ZC_HOST NULL
#define ZC_NAME NULL
#define ZC_REGISTER_FLAGS 0
static DNSServiceRef zcRegRef = NULL;
static pthread_t zcRegThread = { 0 };
static void dcc_zc_reg_cleanup(void)
{
if ( zcRegRef != NULL ) {
DNSServiceRefDeallocate(zcRegRef);
zcRegRef = NULL;
}
}
static void dcc_zc_reg_reply(const DNSServiceRef UNUSED(ref),
const DNSServiceFlags UNUSED(flags),
const DNSServiceErrorType errorCode,
const char *aName,
const char *aRegType,
const char *aDomain,
void * UNUSED(aContext))
{
if ( errorCode ) {
rs_log_error("Aborting zeroconfiguration registration due to error: %d",
errorCode);
dcc_zc_reg_cleanup();
pthread_exit(NULL);
} else {
char *fullName = dcc_zc_full_name(aName, aRegType, aDomain);
rs_log_info("Registered and active as \"%s\"", fullName);
free(fullName);
}
}
static void dcc_zc_actually_register(void *aTxtRecord)
{
size_t txtLen = ( aTxtRecord == NULL ) ? 0
: strlen((char *)aTxtRecord) + 1;
rs_log_info("Registering on port %d for all interfaces", arg_port);
rs_log_info("Distributed compile profile is:\n%s", (char *)aTxtRecord);
DNSServiceErrorType exitValue = DNSServiceRegister(&zcRegRef,
ZC_REGISTER_FLAGS,
ZC_ALL_INTERFACES,
ZC_NAME,
ZC_REG_TYPE,
ZC_DOMAIN,
ZC_HOST,
htons(arg_port),
txtLen,
aTxtRecord,
(DNSServiceRegisterReply)dcc_zc_reg_reply,
ZC_CONTEXT);
free(aTxtRecord);
if ( exitValue == kDNSServiceErr_NoError ) {
while ( TRUE ) {
exitValue = DNSServiceProcessResult(zcRegRef);
if ( exitValue != kDNSServiceErr_NoError ) {
rs_log_error("Unable to handle zeroconfiguration replies: %d",
exitValue);
break;
}
}
} else {
rs_log_error("Unable to register for zeroconfiguration: %d", exitValue);
}
dcc_zc_reg_cleanup();
pthread_exit(NULL);
}
void dcc_register_for_zeroconfig(const char *aTxtRecord)
{
if ( pthread_create(&zcRegThread, NULL,
(void *(*)(void *))dcc_zc_actually_register,
(void *)aTxtRecord) ) {
rs_log_error("Unable to create thread for zeroconfiguration");
}
}
#endif // DARWIN