#include <netinet/in.h>
#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
#include "dns_sd.h"
enum {
- COMMAND_COME_AGAIN = 0,
COMMAND_POLL = 'p',
COMMAND_QUIT = 'q',
COMMAND_POLL_DONE = 'P',
int thread_running;
pthread_mutex_t mutex;
-
+
void *context;
DNSServiceBrowseReply service_browser_callback;
DNSServiceResolveReply service_resolver_callback;
return kDNSServiceErr_BadParam;
- case AVAHI_ERR_LOCAL_COLLISION:
+ case AVAHI_ERR_COLLISION:
return kDNSServiceErr_NameConflict;
case AVAHI_ERR_TOO_MANY_CLIENTS:
case AVAHI_ERR_INVALID_CONFIG:
case AVAHI_ERR_TIMEOUT:
case AVAHI_ERR_DBUS_ERROR:
- case AVAHI_ERR_NOT_CONNECTED:
+ case AVAHI_ERR_DISCONNECTED:
case AVAHI_ERR_NO_DAEMON:
break;
assert(fd >= 0);
if ((r = read(fd, &command, 1)) != 1) {
-
- if (errno == EAGAIN)
- return COMMAND_COME_AGAIN;
-
fprintf(stderr, __FILE__": read() failed: %s\n", r < 0 ? strerror(errno) : "EOF");
return -1;
}
return 0;
}
-static int set_nonblock(int fd) {
- int n;
-
- assert(fd >= 0);
-
- if ((n = fcntl(fd, F_GETFL)) < 0)
- return -1;
-
- if (n & O_NONBLOCK)
- return 0;
-
- return fcntl(fd, F_SETFL, n|O_NONBLOCK);
-}
-
-
static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) {
DNSServiceRef sdref = userdata;
int ret;
case COMMAND_QUIT:
return NULL;
-
- case COMMAND_COME_AGAIN:
- break;
}
}
sdref->thread_fd = fd[0];
sdref->main_fd = fd[1];
- set_nonblock(sdref->main_fd);
-
sdref->client = NULL;
sdref->service_browser = NULL;
sdref->service_resolver = NULL;
if (sdref->simple_poll)
avahi_simple_poll_free(sdref->simple_poll);
-
if (sdref->thread_fd >= 0)
close(sdref->thread_fd);
DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdref) {
DNSServiceErrorType ret = kDNSServiceErr_Unknown;
- int t;
assert(sdref);
assert(sdref->n_ref >= 1);
AVAHI_WARN_LINKAGE;
- sdref_ref(sdref);
-
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
+
+ sdref_ref(sdref);
/* Cleanup notification socket */
- if ((t = read_command(sdref->main_fd)) != COMMAND_POLL_DONE) {
- if (t == COMMAND_COME_AGAIN)
- ret = kDNSServiceErr_Unknown;
+ if (read_command(sdref->main_fd) != COMMAND_POLL_DONE)
goto finish;
- }
if (avahi_simple_poll_dispatch(sdref->simple_poll) < 0)
goto finish;
finish:
- ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex));
-
sdref_unref(sdref);
+
+ ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex));
return ret;
}
void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdref) {
- assert(sdref);
- assert(sdref->n_ref >= 1);
-
AVAHI_WARN_LINKAGE;
- sdref_unref(sdref);
+ if (sdref)
+ sdref_unref(sdref);
}
static void service_browser_callback(
AvahiServiceBrowser *b,
AvahiIfIndex interface,
- AvahiProtocol protocol,
+ AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *name,
const char *type,
const char *domain,
- AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void *userdata) {
DNSServiceRef sdref = userdata;
static void generic_client_callback(AvahiClient *s, AvahiClientState state, void* userdata) {
DNSServiceRef sdref = userdata;
-
+ int error = kDNSServiceErr_Unknown;
+
assert(s);
assert(sdref);
assert(sdref->n_ref >= 1);
switch (state) {
- case AVAHI_CLIENT_DISCONNECTED: {
+
+ case AVAHI_CLIENT_FAILURE:
if (sdref->service_browser_callback)
- sdref->service_browser_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, NULL, NULL, sdref->context);
+ sdref->service_browser_callback(sdref, 0, 0, error, NULL, NULL, NULL, sdref->context);
else if (sdref->service_resolver_callback)
- sdref->service_resolver_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, NULL, 0, 0, NULL, sdref->context);
+ sdref->service_resolver_callback(sdref, 0, 0, error, NULL, NULL, 0, 0, NULL, sdref->context);
else if (sdref->domain_browser_callback)
- sdref->domain_browser_callback(sdref, 0, 0, kDNSServiceErr_Unknown, NULL, sdref->context);
+ sdref->domain_browser_callback(sdref, 0, 0, error, NULL, sdref->context);
break;
- }
case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION:
- case AVAHI_CLIENT_S_INVALID:
case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_CONNECTING:
break;
}
}
assert(ret_sdref);
assert(regtype);
- assert(domain);
assert(callback);
if (interface == kDNSServiceInterfaceIndexLocalOnly || flags != 0) {
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
static void service_resolver_callback(
AvahiServiceResolver *r,
AvahiIfIndex interface,
- AvahiProtocol protocol,
+ AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiResolverEvent event,
const char *name,
const char *type,
const char *domain,
const char *host_name,
- const AvahiAddress *a,
+ AVAHI_GCC_UNUSED const AvahiAddress *a,
uint16_t port,
AvahiStringList *txt,
- AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void *userdata) {
DNSServiceRef sdref = userdata;
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
static void domain_browser_callback(
AvahiDomainBrowser *b,
AvahiIfIndex interface,
- AvahiProtocol protocol,
+ AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *domain,
- AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void *userdata) {
DNSServiceRef sdref = userdata;
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), generic_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}
return;
switch (state) {
- case AVAHI_CLIENT_DISCONNECTED:
-
- reg_report_error(sdref, kDNSServiceErr_NoError);
+ case AVAHI_CLIENT_FAILURE:
+ reg_report_error(sdref, kDNSServiceErr_Unknown);
break;
-
+
case AVAHI_CLIENT_S_RUNNING: {
int ret;
break;
- case AVAHI_CLIENT_S_INVALID:
+ case AVAHI_CLIENT_CONNECTING:
case AVAHI_CLIENT_S_REGISTERING:
/* Ignore */
break;
case AVAHI_ENTRY_GROUP_UNCOMMITED:
/* Ignore */
break;
+
+ case AVAHI_ENTRY_GROUP_FAILURE:
+ /* Inform the user */
+ reg_report_error(sdref, map_error(avahi_client_errno(sdref->client)));
+ break;
+
}
}
DNSServiceErrorType ret = kDNSServiceErr_Unknown;
int error;
DNSServiceRef sdref = NULL;
+ AvahiStringList *txt = NULL;
AVAHI_WARN_LINKAGE;
return kDNSServiceErr_Unsupported;
}
- if (!(sdref = sdref_new()))
+ if (txtRecord && txtLen > 0)
+ if (avahi_string_list_parse(txtRecord, txtLen, &txt) < 0)
+ return kDNSServiceErr_Invalid;
+
+ if (!(sdref = sdref_new())) {
+ avahi_string_list_free(txt);
return kDNSServiceErr_Unknown;
+ }
sdref->context = context;
sdref->service_register_callback = callback;
sdref->service_host = host ? avahi_normalize_name_strdup(host) : NULL;
sdref->service_interface = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface;
sdref->service_port = ntohs(port);
- sdref->service_txt = txtRecord && txtLen > 0 ? avahi_string_list_parse(txtRecord, txtLen) : NULL;
+ sdref->service_txt = txt;
/* Some OOM checking would be cool here */
ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex));
- if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), reg_client_callback, sdref, &error))) {
+ if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, reg_client_callback, sdref, &error))) {
ret = map_error(error);
goto finish;
}