X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-compat-libdns_sd%2Fcompat.c;h=70ccd4b1ef3141b08508a6ad027851e01956fab4;hb=270ea0a81dacf6a2073019d232b6f106e33eeb14;hp=fda5b59262f3b88d2e688b1874b96795d63700b8;hpb=bb14e0a8aa3173c8a6d80b1a9c8b300a452ee9f1;p=catta diff --git a/avahi-compat-libdns_sd/compat.c b/avahi-compat-libdns_sd/compat.c index fda5b59..70ccd4b 100644 --- a/avahi-compat-libdns_sd/compat.c +++ b/avahi-compat-libdns_sd/compat.c @@ -31,21 +31,29 @@ #include #include #include +#include + +#include +#include #include #include #include #include #include + #include +#include +#include #include "warn.h" #include "dns_sd.h" enum { - COMMAND_POLL = 'P', - COMMAND_QUIT = 'Q', - COMMAND_POLLED = 'D' + COMMAND_POLL = 'p', + COMMAND_QUIT = 'q', + COMMAND_POLL_DONE = 'P', + COMMAND_POLL_FAILED = 'F' }; struct _DNSServiceRef_t { @@ -59,7 +67,7 @@ struct _DNSServiceRef_t { int thread_running; pthread_mutex_t mutex; - + void *context; DNSServiceBrowseReply service_browser_callback; DNSServiceResolveReply service_resolver_callback; @@ -103,7 +111,7 @@ static DNSServiceErrorType map_error(int error) { return kDNSServiceErr_BadParam; - case AVAHI_ERR_LOCAL_COLLISION: + case AVAHI_ERR_COLLISION: return kDNSServiceErr_NameConflict; case AVAHI_ERR_TOO_MANY_CLIENTS: @@ -222,25 +230,32 @@ static void * thread_func(void *data) { switch (command) { - case COMMAND_POLL: + case COMMAND_POLL: { + int ret; ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); + + for (;;) { + errno = 0; - - if (avahi_simple_poll_run(sdref->simple_poll) < 0) { - fprintf(stderr, __FILE__": avahi_simple_poll_run() failed.\n"); - ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); - break; - } + if ((ret = avahi_simple_poll_run(sdref->simple_poll)) < 0) { + + if (errno == EINTR) + continue; + + fprintf(stderr, __FILE__": avahi_simple_poll_run() failed: %s\n", strerror(errno)); + } - if (write_command(sdref->thread_fd, COMMAND_POLLED) < 0) { - ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); break; } ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); + + if (write_command(sdref->thread_fd, ret < 0 ? COMMAND_POLL_FAILED : COMMAND_POLL_DONE) < 0) + break; break; + } case COMMAND_QUIT: return NULL; @@ -277,7 +292,7 @@ static DNSServiceRef sdref_new(void) { ASSERT_SUCCESS(pthread_mutexattr_init(&mutex_attr)); pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); - ASSERT_SUCCESS(pthread_mutex_init(&sdref->mutex, NULL)); + ASSERT_SUCCESS(pthread_mutex_init(&sdref->mutex, &mutex_attr)); sdref->thread_running = 0; @@ -290,7 +305,7 @@ static DNSServiceRef sdref_new(void) { if (avahi_simple_poll_prepare(sdref->simple_poll, -1) < 0) goto fail; - /* Queue a initiall POLL command for the thread */ + /* Queue an initial POLL command for the thread */ if (write_command(sdref->main_fd, COMMAND_POLL) < 0) goto fail; @@ -313,24 +328,24 @@ static void sdref_free(DNSServiceRef sdref) { assert(sdref); if (sdref->thread_running) { - write_command(sdref->main_fd, COMMAND_QUIT); + ASSERT_SUCCESS(write_command(sdref->main_fd, COMMAND_QUIT)); avahi_simple_poll_wakeup(sdref->simple_poll); - pthread_join(sdref->thread, NULL); + ASSERT_SUCCESS(pthread_join(sdref->thread, NULL)); } if (sdref->client) avahi_client_free(sdref->client); + if (sdref->simple_poll) + avahi_simple_poll_free(sdref->simple_poll); + if (sdref->thread_fd >= 0) close(sdref->thread_fd); if (sdref->main_fd >= 0) close(sdref->main_fd); - if (sdref->simple_poll) - avahi_simple_poll_free(sdref->simple_poll); - - pthread_mutex_destroy(&sdref->mutex); + ASSERT_SUCCESS(pthread_mutex_destroy(&sdref->mutex)); avahi_free(sdref->service_name); avahi_free(sdref->service_name_chosen); @@ -375,12 +390,12 @@ DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdref) { AVAHI_WARN_LINKAGE; - sdref_ref(sdref); - ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); + + sdref_ref(sdref); /* Cleanup notification socket */ - if (read_command(sdref->main_fd) != COMMAND_POLLED) + if (read_command(sdref->main_fd) != COMMAND_POLL_DONE) goto finish; if (avahi_simple_poll_dispatch(sdref->simple_poll) < 0) @@ -402,31 +417,29 @@ DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdref) { 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; @@ -459,27 +472,27 @@ static void service_browser_callback( 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_DISCONNECTED: 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: break; } @@ -547,35 +560,35 @@ 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; - char host_name_fixed[AVAHI_DOMAIN_NAME_MAX]; assert(r); assert(sdref); assert(sdref->n_ref >= 1); - host_name = add_trailing_dot(host_name, host_name_fixed, sizeof(host_name_fixed)); - switch (event) { case AVAHI_RESOLVER_FOUND: { + char host_name_fixed[AVAHI_DOMAIN_NAME_MAX]; char full_name[AVAHI_DOMAIN_NAME_MAX]; int ret; char *p = NULL; size_t l = 0; + host_name = add_trailing_dot(host_name, host_name_fixed, sizeof(host_name_fixed)); + if ((p = avahi_new0(char, (l = avahi_string_list_serialize(txt, NULL, 0))+1))) avahi_string_list_serialize(txt, p, l); @@ -592,7 +605,7 @@ static void service_resolver_callback( case AVAHI_RESOLVER_FAILURE: sdref->service_resolver_callback(sdref, 0, interface, map_error(avahi_client_errno(sdref->client)), NULL, NULL, 0, 0, NULL, sdref->context); - + break; } } @@ -679,10 +692,10 @@ int DNSSD_API DNSServiceConstructFullName ( 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; @@ -847,12 +860,10 @@ static void reg_client_callback(AvahiClient *s, AvahiClientState state, void* us return; switch (state) { - case AVAHI_CLIENT_DISCONNECTED: { - - reg_report_error(sdref, kDNSServiceErr_NoError); + case AVAHI_CLIENT_DISCONNECTED: + reg_report_error(sdref, kDNSServiceErr_Unknown); break; - } - + case AVAHI_CLIENT_S_RUNNING: { int ret; @@ -861,6 +872,7 @@ static void reg_client_callback(AvahiClient *s, AvahiClientState state, void* us /* If the service name is taken from the host name, copy that */ avahi_free(sdref->service_name_chosen); + sdref->service_name_chosen = NULL; if (!(n = avahi_client_get_host_name(sdref->client))) { reg_report_error(sdref, map_error(avahi_client_errno(sdref->client))); @@ -890,7 +902,6 @@ static void reg_client_callback(AvahiClient *s, AvahiClientState state, void* us break; - case AVAHI_CLIENT_S_INVALID: case AVAHI_CLIENT_S_REGISTERING: /* Ignore */ break; @@ -940,6 +951,12 @@ static void reg_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState st 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; + } } @@ -960,6 +977,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister ( DNSServiceErrorType ret = kDNSServiceErr_Unknown; int error; DNSServiceRef sdref = NULL; + AvahiStringList *txt = NULL; AVAHI_WARN_LINKAGE; @@ -972,8 +990,14 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister ( 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; @@ -984,7 +1008,9 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister ( 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 ? 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));