1941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering/*** 2941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering This file is part of avahi. 3a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi is free software; you can redistribute it and/or modify it 5941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering under the terms of the GNU Lesser General Public License as 6941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering published by the Free Software Foundation; either version 2.1 of the 7941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering License, or (at your option) any later version. 8a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 9941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 10941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 12941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering Public License for more details. 13a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 14941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering You should have received a copy of the GNU Lesser General Public 15941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering License along with avahi; if not, write to the Free Software 16941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 17941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering USA. 18941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering***/ 19941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 20941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#ifdef HAVE_CONFIG_H 21941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <config.h> 22941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#endif 23941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 24941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <pthread.h> 25941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <assert.h> 26941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <unistd.h> 27941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <stdio.h> 28941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <errno.h> 29941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <string.h> 30941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <signal.h> 31941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <netinet/in.h> 32e559962871b8564afb6199f3b5fe24cd47607745Lennart Poettering#include <fcntl.h> 33941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 34270ea0a81dacf6a2073019d232b6f106e33eeb14Sebastien Estienne#include <sys/types.h> 35270ea0a81dacf6a2073019d232b6f106e33eeb14Sebastien Estienne#include <sys/socket.h> 36270ea0a81dacf6a2073019d232b6f106e33eeb14Sebastien Estienne 37941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <avahi-common/simple-watch.h> 388e46e738cae449bf44232c66e973c8e9e15fbcb5Robert Ginda#include "avahi-common/avahi-malloc.h" 39941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <avahi-common/error.h> 40941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <avahi-common/domain.h> 41941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <avahi-common/alternative.h> 420c54764cf19428a0c52724a75ddf3368e3899209Lennart Poettering 43941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include <avahi-client/client.h> 440c54764cf19428a0c52724a75ddf3368e3899209Lennart Poettering#include <avahi-client/publish.h> 450c54764cf19428a0c52724a75ddf3368e3899209Lennart Poettering#include <avahi-client/lookup.h> 46941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 47941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include "warn.h" 48941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#include "dns_sd.h" 49941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 50941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringenum { 51786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering COMMAND_POLL = 'p', 52786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering COMMAND_QUIT = 'q', 539da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering COMMAND_POLL_DONE = 'P', 549da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering COMMAND_POLL_FAILED = 'F' 55941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering}; 56941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 57e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poetteringstruct type_info { 58e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering char *type; 59e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering AvahiStringList *subtypes; 60e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering int n_subtypes; 61e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering}; 62e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 63941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstruct _DNSServiceRef_t { 64941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int n_ref; 65a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 66941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiSimplePoll *simple_poll; 67941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 68941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int thread_fd, main_fd; 69941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 70941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering pthread_t thread; 71941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int thread_running; 72941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 73941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering pthread_mutex_t mutex; 74a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 75941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *context; 76941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceBrowseReply service_browser_callback; 77941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceResolveReply service_resolver_callback; 78941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceDomainEnumReply domain_browser_callback; 79941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRegisterReply service_register_callback; 80e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceQueryRecordReply query_resolver_callback; 81941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 82941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiClient *client; 83941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiServiceBrowser *service_browser; 84941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiServiceResolver *service_resolver; 85941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiDomainBrowser *domain_browser; 86e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AvahiRecordBrowser *record_browser; 87941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 88e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering struct type_info type_info; 89e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering char *service_name, *service_name_chosen, *service_domain, *service_host; 90941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering uint16_t service_port; 91941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex service_interface; 92941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiStringList *service_txt; 93941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 94941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiEntryGroup *entry_group; 95941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering}; 96941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 97941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering#define ASSERT_SUCCESS(r) { int __ret = (r); assert(__ret == 0); } 98941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 99941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic DNSServiceErrorType map_error(int error) { 100941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (error) { 101941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_OK : 102941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_NoError; 103a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 104941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_BAD_STATE : 105941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_BadState; 106a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 107941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_HOST_NAME: 108941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_DOMAIN_NAME: 109941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_TTL: 110941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_IS_PATTERN: 111941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_RECORD: 112941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_SERVICE_NAME: 113941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_SERVICE_TYPE: 114941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_PORT: 115941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_KEY: 116941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_ADDRESS: 117c1d9b9cffd6f756339c1d98a2d2914d49195cb41Lennart Poettering case AVAHI_ERR_INVALID_SERVICE_SUBTYPE: 118941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_BadParam; 119941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 120941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 121f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering case AVAHI_ERR_COLLISION: 122941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_NameConflict; 123941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 124941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_TOO_MANY_CLIENTS: 125941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_TOO_MANY_OBJECTS: 126941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_TOO_MANY_ENTRIES: 127941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_ACCESS_DENIED: 128941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Refused; 129941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 130941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_OPERATION: 131941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_OBJECT: 132941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Invalid; 133941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 134941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_NO_MEMORY: 135941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_NoMemory; 136941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 137941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_INTERFACE: 138941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_PROTOCOL: 139941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_BadInterfaceIndex; 140a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 141941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_FLAGS: 142941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_BadFlags; 143a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 144941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_NOT_FOUND: 145941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_NoSuchName; 146a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 147941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_VERSION_MISMATCH: 148941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Incompatible; 149941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 150941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_NO_NETWORK: 151941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_OS: 152941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_INVALID_CONFIG: 153941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_TIMEOUT: 154941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_DBUS_ERROR: 1554e2113a7d5b702ff070e8220b32662bb00ae02ddLennart Poettering case AVAHI_ERR_DISCONNECTED: 156941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ERR_NO_DAEMON: 157941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 158941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 159941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 160941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 161941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unknown; 162941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 163941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 164e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poetteringstatic void type_info_init(struct type_info *i) { 165e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering assert(i); 166e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->type = NULL; 167e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->subtypes = NULL; 168e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->n_subtypes = 0; 169e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering} 170e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 171e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poetteringstatic void type_info_free(struct type_info *i) { 172e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering assert(i); 173e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 174e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_free(i->type); 175e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_string_list_free(i->subtypes); 176e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 177e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_init(i); 178e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering} 179e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 180e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poetteringstatic int type_info_parse(struct type_info *i, const char *t) { 181e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering char *token = NULL; 182a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 183e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering assert(i); 184e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering assert(t); 185e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 186e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_init(i); 187e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 188e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering for (;;) { 189e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering size_t l; 190e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 191e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (*t == 0) 192e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering break; 193a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 194e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering l = strcspn(t, ","); 195e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 196e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (l <= 0) 197e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering goto fail; 198a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 199e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering token = avahi_strndup(t, l); 200e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 201e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!token) 202e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering goto fail; 203e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 204e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!i->type) { 205e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering /* This is the first token, hence the main type */ 206e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 207e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!avahi_is_valid_service_type_strict(token)) 208e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering goto fail; 209e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 210e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->type = token; 211e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering token = NULL; 212e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } else { 213e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering char *fst; 214a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 215e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering /* This is not the first token, hence a subtype */ 216e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 217e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!(fst = avahi_strdup_printf("%s._sub.%s", token, i->type))) 218e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering goto fail; 219e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 220e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!avahi_is_valid_service_subtype(fst)) { 221e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_free(fst); 222e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering goto fail; 223e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } 224e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 225e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->subtypes = avahi_string_list_add(i->subtypes, fst); 226e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_free(fst); 227e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 228e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_free(token); 229e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering token = NULL; 230e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 231e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering i->n_subtypes++; 232e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } 233e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 234e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering t += l; 235e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 236e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (*t == ',') 237e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering t++; 238e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } 239e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 240e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (i->type) 241e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering return 0; 242a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 243e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poetteringfail: 244e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(i); 245e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_free(token); 246e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering return -1; 247e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering} 248e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 24926ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poetteringstatic const char *add_trailing_dot(const char *s, char *buf, size_t buf_len) { 25026ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering if (!s) 25126ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering return NULL; 25226ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 25326ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering if (*s == 0) 25426ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering return s; 25526ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 25626ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering if (s[strlen(s)-1] == '.') 25726ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering return s; 25826ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 25926ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering snprintf(buf, buf_len, "%s.", s); 26026ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering return buf; 26126ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering} 26226ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 263941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic int read_command(int fd) { 264941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ssize_t r; 265941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering char command; 266941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 267941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(fd >= 0); 268a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 269941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((r = read(fd, &command, 1)) != 1) { 270941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering fprintf(stderr, __FILE__": read() failed: %s\n", r < 0 ? strerror(errno) : "EOF"); 271941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return -1; 272941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 273941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 274941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return command; 275941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 276941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 277941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic int write_command(int fd, char reply) { 278941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(fd >= 0); 279941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 280941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (write(fd, &reply, 1) != 1) { 281941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); 282941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return -1; 283941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 284941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 285941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return 0; 286941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 287941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 288941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) { 289941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 290941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int ret; 291a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 292941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 293a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 294941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 295941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 296941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering/* fprintf(stderr, "pre-syscall\n"); */ 297941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = poll(ufds, nfds, timeout); 298941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering/* fprintf(stderr, "post-syscall\n"); */ 299a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 300941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 301941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 302941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 303941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 304941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 305941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void * thread_func(void *data) { 306941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = data; 307941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sigset_t mask; 308941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 309941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sigfillset(&mask); 310941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering pthread_sigmask(SIG_BLOCK, &mask, NULL); 311a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 312941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->thread = pthread_self(); 313941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->thread_running = 1; 314941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 315941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering for (;;) { 316941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering char command; 317941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 318941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((command = read_command(sdref->thread_fd)) < 0) 319941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 320941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 321941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering/* fprintf(stderr, "Command: %c\n", command); */ 322a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 323941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (command) { 324941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 3259da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering case COMMAND_POLL: { 3269da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering int ret; 327941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 328941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 3299da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering 3309da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering for (;;) { 3319da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering errno = 0; 332a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3339da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering if ((ret = avahi_simple_poll_run(sdref->simple_poll)) < 0) { 3349da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering 3359da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering if (errno == EINTR) 3369da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering continue; 337a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3389da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering fprintf(stderr, __FILE__": avahi_simple_poll_run() failed: %s\n", strerror(errno)); 3399da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering } 3409da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering 341941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 342941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 343941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 344941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 345786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering 3469da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering if (write_command(sdref->thread_fd, ret < 0 ? COMMAND_POLL_FAILED : COMMAND_POLL_DONE) < 0) 347786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering break; 348a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 349941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 3509da0241b9c1bf751605ba11fa6d4c75e34fe5f2bLennart Poettering } 351941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 352941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case COMMAND_QUIT: 353941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return NULL; 354941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 355a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 356941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 357941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 358941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return NULL; 359941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 360941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 361941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic DNSServiceRef sdref_new(void) { 362941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int fd[2] = { -1, -1 }; 363941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = NULL; 364941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering pthread_mutexattr_t mutex_attr; 365941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 366941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) 367941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 368941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 369941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref = avahi_new(struct _DNSServiceRef_t, 1))) 370941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 371941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 372941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->n_ref = 1; 373941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->thread_fd = fd[0]; 374941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->main_fd = fd[1]; 375941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 376941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->client = NULL; 377941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_browser = NULL; 378941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_resolver = NULL; 379941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->domain_browser = NULL; 380941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->entry_group = NULL; 381941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 382e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering sdref->service_name = sdref->service_name_chosen = sdref->service_domain = sdref->service_host = NULL; 383941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_txt = NULL; 384941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 385e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_init(&sdref->type_info); 386e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 387941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutexattr_init(&mutex_attr)); 388941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); 38945513c3b363228f92572d853e63085b5db60c166Lennart Poettering ASSERT_SUCCESS(pthread_mutex_init(&sdref->mutex, &mutex_attr)); 390941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 391941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->thread_running = 0; 392941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 393941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->simple_poll = avahi_simple_poll_new())) 394941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 395941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 396941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_simple_poll_set_func(sdref->simple_poll, poll_func, sdref); 397941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 398941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Start simple poll */ 399941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (avahi_simple_poll_prepare(sdref->simple_poll, -1) < 0) 400941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 401941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 402786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering /* Queue an initial POLL command for the thread */ 403941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (write_command(sdref->main_fd, COMMAND_POLL) < 0) 404941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 405a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 406941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (pthread_create(&sdref->thread, NULL, thread_func, sdref) != 0) 407941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto fail; 408941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 409941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->thread_running = 1; 410a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 411941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return sdref; 412941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 413941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfail: 414941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 415941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref) 416941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRefDeallocate(sdref); 417941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 418941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return NULL; 419941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 420941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 421941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void sdref_free(DNSServiceRef sdref) { 422941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 423a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 424941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->thread_running) { 425786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering ASSERT_SUCCESS(write_command(sdref->main_fd, COMMAND_QUIT)); 426941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_simple_poll_wakeup(sdref->simple_poll); 427786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering ASSERT_SUCCESS(pthread_join(sdref->thread, NULL)); 428941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 429941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 430941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->client) 431941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_client_free(sdref->client); 432941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 433786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering if (sdref->simple_poll) 434786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering avahi_simple_poll_free(sdref->simple_poll); 435786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering 436941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->thread_fd >= 0) 437941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering close(sdref->thread_fd); 438941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 439941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->main_fd >= 0) 440941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering close(sdref->main_fd); 441941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 442786a6a7fa3840d06e64f7429e134ddb06cc1deddLennart Poettering ASSERT_SUCCESS(pthread_mutex_destroy(&sdref->mutex)); 443941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 444941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_name); 445941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_name_chosen); 446941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_domain); 447941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_host); 448941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 449e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(&sdref->type_info); 450a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 451941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_string_list_free(sdref->service_txt); 452a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 453941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref); 454941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 455941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 456941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void sdref_ref(DNSServiceRef sdref) { 457941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 458941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 459941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 460941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->n_ref++; 461941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 462941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 463941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void sdref_unref(DNSServiceRef sdref) { 464941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 465941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 466941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 467941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (--(sdref->n_ref) <= 0) 468941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref_free(sdref); 469941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 470941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 471941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringint DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdref) { 472941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 473941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 474a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4755b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering if (!sdref || sdref->n_ref <= 0) 4765b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering return -1; 4775b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 478941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return sdref->main_fd; 479941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 480941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 481941853354848fca4cc39bd72e6f34ca54443a9c8Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdref) { 482941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 483941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 484941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 485941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 4865b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering if (!sdref || sdref->n_ref <= 0) 4875b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering return kDNSServiceErr_BadParam; 488a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4890d0c9486e3fe26fdd67624ee57961ba2d5846ebbLennart Poettering sdref_ref(sdref); 4905b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 4915b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 492a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 493941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Cleanup notification socket */ 49444781dc4d0c3dfdc5d78900d56e93d3450e82f55Lennart Poettering if (read_command(sdref->main_fd) != COMMAND_POLL_DONE) 495941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 496a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 497941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (avahi_simple_poll_dispatch(sdref->simple_poll) < 0) 498941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 499941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 500941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->n_ref > 1) /* Perhaps we should die */ 501941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 502941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Dispatch events */ 503941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (avahi_simple_poll_prepare(sdref->simple_poll, -1) < 0) 504941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 505941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 506941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->n_ref > 1) 507941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 508941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Request the poll */ 509941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (write_command(sdref->main_fd, COMMAND_POLL) < 0) 510941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 511a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 512941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoError; 513a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 514941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfinish: 515941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 5160d0c9486e3fe26fdd67624ee57961ba2d5846ebbLennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 517a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5185b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering sdref_unref(sdref); 5195b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 520941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 521941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 522941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 523941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringvoid DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdref) { 524941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 525941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 526caa787a5490efb94015ae3f26e79983573997a2dLennart Poettering if (sdref) 527caa787a5490efb94015ae3f26e79983573997a2dLennart Poettering sdref_unref(sdref); 528941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 529941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 530941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void service_browser_callback( 531941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiServiceBrowser *b, 532941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex interface, 533854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiProtocol protocol, 534941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiBrowserEvent event, 535941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *name, 536941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *type, 537941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *domain, 538854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, 539941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *userdata) { 540941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 541941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 54226ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering char type_fixed[AVAHI_DOMAIN_NAME_MAX], domain_fixed[AVAHI_DOMAIN_NAME_MAX]; 543941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(b); 544941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 545941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 546941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 54726ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering type = add_trailing_dot(type, type_fixed, sizeof(type_fixed)); 54826ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering domain = add_trailing_dot(domain, domain_fixed, sizeof(domain_fixed)); 549a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 550941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (event) { 551941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_NEW: 552941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_browser_callback(sdref, kDNSServiceFlagsAdd, interface, kDNSServiceErr_NoError, name, type, domain, sdref->context); 553941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 554941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 555941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_REMOVE: 556941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_browser_callback(sdref, 0, interface, kDNSServiceErr_NoError, name, type, domain, sdref->context); 557941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 558941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 559941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_FAILURE: 560bb14e0a8aa3173c8a6d80b1a9c8b300a452ee9f1Lennart Poettering sdref->service_browser_callback(sdref, 0, interface, map_error(avahi_client_errno(sdref->client)), NULL, NULL, NULL, sdref->context); 561941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 562a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 563941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_CACHE_EXHAUSTED: 564941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_ALL_FOR_NOW: 565941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 566941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 567941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 568941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 569941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void generic_client_callback(AvahiClient *s, AvahiClientState state, void* userdata) { 570941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 571f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering int error = kDNSServiceErr_Unknown; 572a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 573941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(s); 574941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 575941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 576941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 577941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (state) { 5786f37f0e1126ad3776b80dbd64701f38a58738921Lennart Poettering 5796f37f0e1126ad3776b80dbd64701f38a58738921Lennart Poettering case AVAHI_CLIENT_FAILURE: 580941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 581941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->service_browser_callback) 582f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering sdref->service_browser_callback(sdref, 0, 0, error, NULL, NULL, NULL, sdref->context); 583941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering else if (sdref->service_resolver_callback) 584f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering sdref->service_resolver_callback(sdref, 0, 0, error, NULL, NULL, 0, 0, NULL, sdref->context); 585941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering else if (sdref->domain_browser_callback) 586f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering sdref->domain_browser_callback(sdref, 0, 0, error, NULL, sdref->context); 587e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering else if (sdref->query_resolver_callback) 588e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering sdref->query_resolver_callback(sdref, 0, 0, error, NULL, 0, 0, 0, NULL, 0, sdref->context); 589941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 590941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 591941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 592941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_CLIENT_S_RUNNING: 593941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_CLIENT_S_COLLISION: 594941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_CLIENT_S_REGISTERING: 5956ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering case AVAHI_CLIENT_CONNECTING: 596941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 597941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 598941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 599941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 600941853354848fca4cc39bd72e6f34ca54443a9c8Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceBrowse( 601e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering DNSServiceRef *ret_sdref, 602e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering DNSServiceFlags flags, 603e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering uint32_t interface, 604e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering const char *regtype, 605e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering const char *domain, 606e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering DNSServiceBrowseReply callback, 607e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering void *context) { 608941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 609941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 610941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int error; 611941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = NULL; 612941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex ifindex; 613e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering struct type_info type_info; 614a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 615941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 616c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd 617511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!ret_sdref || !regtype) 618c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd return kDNSServiceErr_BadParam; 619c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd *ret_sdref = NULL; 620c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd 6211c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering if (interface == kDNSServiceInterfaceIndexLocalOnly || flags != 0) { 6221c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering AVAHI_WARN_UNSUPPORTED; 623941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unsupported; 6241c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering } 625941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 626e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_init(&type_info); 627a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 628e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (type_info_parse(&type_info, regtype) < 0 || type_info.n_subtypes > 1) { 629e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(&type_info); 630e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 631e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!avahi_is_valid_service_type_generic(regtype)) 632e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering return kDNSServiceErr_Unsupported; 633e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } else 634e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering regtype = type_info.subtypes ? (char*) type_info.subtypes->text : type_info.type; 635a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 636e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (!(sdref = sdref_new())) { 637e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(&type_info); 638941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unknown; 639e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } 640941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 641941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->context = context; 642941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_browser_callback = callback; 643941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 644941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 645a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6466ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) { 647941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(error); 648941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 649941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 650941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 651941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ifindex = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface; 652a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 653941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->service_browser = avahi_service_browser_new(sdref->client, ifindex, AVAHI_PROTO_UNSPEC, regtype, domain, 0, service_browser_callback, sdref))) { 654941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 655941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 656941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 657a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 658941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoError; 659941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering *ret_sdref = sdref; 660a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 661941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfinish: 662941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 663941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 664a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 665941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (ret != kDNSServiceErr_NoError) 666941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRefDeallocate(sdref); 667941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 668e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(&type_info); 669e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 670941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 671c8879d3cf7f23325346e1bd601924c6b1e0a21d1Lennart Poettering} 672941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 673941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void service_resolver_callback( 674941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiServiceResolver *r, 675941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex interface, 676854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiProtocol protocol, 677941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiResolverEvent event, 678941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *name, 679941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *type, 680941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *domain, 681941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *host_name, 682854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED const AvahiAddress *a, 683941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering uint16_t port, 684941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiStringList *txt, 685854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, 686941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *userdata) { 687941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 688941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 689941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 690941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(r); 691941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 692941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 693941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 694941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (event) { 695941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_RESOLVER_FOUND: { 696941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 69745513c3b363228f92572d853e63085b5db60c166Lennart Poettering char host_name_fixed[AVAHI_DOMAIN_NAME_MAX]; 69826ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering char full_name[AVAHI_DOMAIN_NAME_MAX]; 699941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int ret; 700941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering char *p = NULL; 701941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering size_t l = 0; 702941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 70345513c3b363228f92572d853e63085b5db60c166Lennart Poettering host_name = add_trailing_dot(host_name, host_name_fixed, sizeof(host_name_fixed)); 70445513c3b363228f92572d853e63085b5db60c166Lennart Poettering 705941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((p = avahi_new0(char, (l = avahi_string_list_serialize(txt, NULL, 0))+1))) 706941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_string_list_serialize(txt, p, l); 707941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 708d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering ret = avahi_service_name_join(full_name, sizeof(full_name), name, type, domain); 709941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(ret == AVAHI_OK); 71026ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 71126ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering strcat(full_name, "."); 712a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 71382aabd487bd00b79147ee23f4f76d692fdd0ced3Lennart Poettering sdref->service_resolver_callback(sdref, 0, interface, kDNSServiceErr_NoError, full_name, host_name, htons(port), l, (unsigned char*) p, sdref->context); 714941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 715941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(p); 716941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 717941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 718941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 719941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_RESOLVER_FAILURE: 720bb14e0a8aa3173c8a6d80b1a9c8b300a452ee9f1Lennart Poettering sdref->service_resolver_callback(sdref, 0, interface, map_error(avahi_client_errno(sdref->client)), NULL, NULL, 0, 0, NULL, sdref->context); 72145513c3b363228f92572d853e63085b5db60c166Lennart Poettering break; 722941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 723941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 724941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 725941853354848fca4cc39bd72e6f34ca54443a9c8Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceResolve( 726941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef *ret_sdref, 727941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceFlags flags, 728941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering uint32_t interface, 729941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *name, 730941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *regtype, 731941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *domain, 732941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceResolveReply callback, 733941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *context) { 734941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 735941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 736941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int error; 737941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = NULL; 738941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex ifindex; 739941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 740941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 741941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 742511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!ret_sdref || !name || !regtype || !domain || !callback) 7435b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering return kDNSServiceErr_BadParam; 7445b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering *ret_sdref = NULL; 7455b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 7461c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering if (interface == kDNSServiceInterfaceIndexLocalOnly || flags != 0) { 7471c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering AVAHI_WARN_UNSUPPORTED; 748941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unsupported; 7491c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering } 750941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 751941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref = sdref_new())) 752941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unknown; 753941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 754941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->context = context; 755941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_resolver_callback = callback; 756941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 757941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 758a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 7596ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) { 760941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(error); 761941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 762941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 763941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 764941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ifindex = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface; 765a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 766941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->service_resolver = avahi_service_resolver_new(sdref->client, ifindex, AVAHI_PROTO_UNSPEC, name, regtype, domain, AVAHI_PROTO_UNSPEC, 0, service_resolver_callback, sdref))) { 767941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 768941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 769941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 770a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 771941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 772941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoError; 773941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering *ret_sdref = sdref; 774a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 775941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfinish: 776941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 777941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 778a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 779941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (ret != kDNSServiceErr_NoError) 780941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRefDeallocate(sdref); 781941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 782941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 783941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 784941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 785941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringint DNSSD_API DNSServiceConstructFullName ( 786941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering char *fullName, 787a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering const char *service, 788941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *regtype, 789941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *domain) { 790941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 791941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 792941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 793511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!fullName || !regtype || !domain) 794511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering return -1; 795941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 796d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering if (avahi_service_name_join(fullName, kDNSServiceMaxDomainName, service, regtype, domain) < 0) 797941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return -1; 798a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 799941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return 0; 800941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 801941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 802941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void domain_browser_callback( 803941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiDomainBrowser *b, 804941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex interface, 805854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiProtocol protocol, 806941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiBrowserEvent event, 807941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *domain, 808854f901f491ccda79aee11edc3d59109cb229d28Lennart Poettering AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, 809941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *userdata) { 810941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 811941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 81226ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering static char domain_fixed[AVAHI_DOMAIN_NAME_MAX]; 813941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 814941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(b); 815941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 816941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 817941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 81826ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering domain = add_trailing_dot(domain, domain_fixed, sizeof(domain_fixed)); 81926ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering 820941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (event) { 821941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_NEW: 822941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->domain_browser_callback(sdref, kDNSServiceFlagsAdd, interface, kDNSServiceErr_NoError, domain, sdref->context); 823941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 824941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 825941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_REMOVE: 826941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->domain_browser_callback(sdref, 0, interface, kDNSServiceErr_NoError, domain, sdref->context); 827941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 828941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 829941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_FAILURE: 830bb14e0a8aa3173c8a6d80b1a9c8b300a452ee9f1Lennart Poettering sdref->domain_browser_callback(sdref, 0, interface, map_error(avahi_client_errno(sdref->client)), domain, sdref->context); 831941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 832a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 833941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_CACHE_EXHAUSTED: 834941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_BROWSER_ALL_FOR_NOW: 835941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 836941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 837941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 838941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 839941853354848fca4cc39bd72e6f34ca54443a9c8Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains( 840941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef *ret_sdref, 841941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceFlags flags, 842941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering uint32_t interface, 843941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceDomainEnumReply callback, 844941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering void *context) { 845941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 846941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 847941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int error; 848941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = NULL; 849941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AvahiIfIndex ifindex; 850941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 851941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 852941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 853511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!ret_sdref || !callback) 8545b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering return kDNSServiceErr_BadParam; 8555b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering *ret_sdref = NULL; 8565b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 857941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (interface == kDNSServiceInterfaceIndexLocalOnly || 8581c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering (flags != kDNSServiceFlagsBrowseDomains && flags != kDNSServiceFlagsRegistrationDomains)) { 8591c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering AVAHI_WARN_UNSUPPORTED; 860941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unsupported; 8611c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering } 862941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 863941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref = sdref_new())) 864941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unknown; 865941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 866941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->context = context; 867941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->domain_browser_callback = callback; 868941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 869941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 870a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 8716ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) { 872941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(error); 873941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 874941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 875941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 876941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ifindex = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface; 877a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 878cc10c2a6a4a29d65a72fb33b7cf6206e5f04be30Lennart Poettering if (!(sdref->domain_browser = avahi_domain_browser_new(sdref->client, ifindex, AVAHI_PROTO_UNSPEC, "local", 879941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering flags == kDNSServiceFlagsRegistrationDomains ? AVAHI_DOMAIN_BROWSER_REGISTER : AVAHI_DOMAIN_BROWSER_BROWSE, 880941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 0, domain_browser_callback, sdref))) { 881941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 882941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 883941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 884a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 885941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoError; 886941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering *ret_sdref = sdref; 887a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 888941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfinish: 889941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 890941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 891a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 892941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (ret != kDNSServiceErr_NoError) 893941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRefDeallocate(sdref); 894941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 895941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 896941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 897941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 898941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void reg_report_error(DNSServiceRef sdref, DNSServiceErrorType error) { 89926ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering char regtype_fixed[AVAHI_DOMAIN_NAME_MAX], domain_fixed[AVAHI_DOMAIN_NAME_MAX]; 90026ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering const char *regtype, *domain; 901941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 902941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 903941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 904d4fd0d73b1d646f3708f1fdcbca0d494dda7e475Lennart Poettering if (!sdref->service_register_callback) 905d4fd0d73b1d646f3708f1fdcbca0d494dda7e475Lennart Poettering return; 906941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 907e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering regtype = add_trailing_dot(sdref->type_info.type, regtype_fixed, sizeof(regtype_fixed)); 90826ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering domain = add_trailing_dot(sdref->service_domain, domain_fixed, sizeof(domain_fixed)); 909a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 910941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_register_callback( 911941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref, 0, error, 912941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_name_chosen ? sdref->service_name_chosen : sdref->service_name, 91326ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering regtype, 91426ff12dc7f06b0031050938d297e6ef94931e8bfLennart Poettering domain, 915941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->context); 916941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 917941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 918941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic int reg_create_service(DNSServiceRef sdref) { 919941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int ret; 920e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering AvahiStringList *l; 921a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 922941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 923941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 924941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 925941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((ret = avahi_entry_group_add_service_strlst( 926941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->entry_group, 927941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_interface, 928941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_PROTO_UNSPEC, 929941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 0, 930941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_name_chosen, 931e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering sdref->type_info.type, 932941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_domain, 933941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_host, 934941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_port, 935941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_txt)) < 0) 936941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 937941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 938e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering for (l = sdref->type_info.subtypes; l; l = l->next) { 9391adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering /* Create a subtype entry */ 9401adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering 9411adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering if (avahi_entry_group_add_service_subtype( 9421adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering sdref->entry_group, 9431adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering sdref->service_interface, 9441adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering AVAHI_PROTO_UNSPEC, 9451adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering 0, 9461adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering sdref->service_name_chosen, 947e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering sdref->type_info.type, 9481adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering sdref->service_domain, 949e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering (const char*) l->text) < 0) 9501adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering return ret; 9511adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering } 9521adbc218354388dd59c68267c363d2fbcc75eaadLennart Poettering 953941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((ret = avahi_entry_group_commit(sdref->entry_group)) < 0) 954941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 955941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 956941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return 0; 957941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 958941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 959941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void reg_client_callback(AvahiClient *s, AvahiClientState state, void* userdata) { 960941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 961941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 962941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(s); 963941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref); 964941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->n_ref >= 1); 965941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 966941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* We've not been setup completely */ 967941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!sdref->entry_group) 968941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 969a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 970941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (state) { 9716f37f0e1126ad3776b80dbd64701f38a58738921Lennart Poettering case AVAHI_CLIENT_FAILURE: 972f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering reg_report_error(sdref, kDNSServiceErr_Unknown); 973f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering break; 974941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 975941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_CLIENT_S_RUNNING: { 976941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int ret; 977941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 978941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!sdref->service_name) { 979941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *n; 980941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* If the service name is taken from the host name, copy that */ 981941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 982941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_name_chosen); 983fee238b3a20c8fbb34af6b08995df2265131bee6Lennart Poettering sdref->service_name_chosen = NULL; 984941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 985941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(n = avahi_client_get_host_name(sdref->client))) { 986941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, map_error(avahi_client_errno(sdref->client))); 987941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 988941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 989941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 990941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->service_name_chosen = avahi_strdup(n))) { 991941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, kDNSServiceErr_NoMemory); 992941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 993941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 994941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 995373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering 996373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering if (!sdref->service_name_chosen) { 997373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering 998373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering assert(sdref->service_name); 999a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1000373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering if (!(sdref->service_name_chosen = avahi_strdup(sdref->service_name))) { 1001373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering reg_report_error(sdref, kDNSServiceErr_NoMemory); 1002373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering return; 1003373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering } 1004373dc531148992c6a5cf57b2fae29286afd70488Lennart Poettering } 1005a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1006941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Register the service */ 1007941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1008941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((ret = reg_create_service(sdref)) < 0) { 1009941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, map_error(ret)); 1010941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 1011941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1012a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1013941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1014941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1015a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1016941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_CLIENT_S_COLLISION: 1017c1e5b725e8e769c8ac1f5df97aac53896b05af43Lennart Poettering case AVAHI_CLIENT_S_REGISTERING: 1018941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1019941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Remove our entry */ 1020941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_entry_group_reset(sdref->entry_group); 1021a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1022941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1023941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 10246ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering case AVAHI_CLIENT_CONNECTING: 1025941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Ignore */ 1026941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1027941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1028941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1029941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 1030941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1031941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringstatic void reg_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { 1032941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = userdata; 1033941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1034941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(g); 1035941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1036941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering switch (state) { 1037941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ENTRY_GROUP_ESTABLISHED: 1038fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1039941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Inform the user */ 1040941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, kDNSServiceErr_NoError); 1041941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1042941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1043941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1044941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ENTRY_GROUP_COLLISION: { 1045941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering char *n; 1046941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int ret; 1047a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1048941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Remove our entry */ 1049941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_entry_group_reset(sdref->entry_group); 1050941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1051941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering assert(sdref->service_name_chosen); 1052941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1053941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Pick a new name */ 1054941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(n = avahi_alternative_service_name(sdref->service_name_chosen))) { 1055941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, kDNSServiceErr_NoMemory); 1056941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 1057941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1058941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering avahi_free(sdref->service_name_chosen); 1059941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_name_chosen = n; 1060941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1061941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Register the service with that new name */ 1062941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((ret = reg_create_service(sdref)) < 0) { 1063941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering reg_report_error(sdref, map_error(ret)); 1064941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return; 1065941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1066a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1067941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1068941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1069941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1070941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ENTRY_GROUP_REGISTERING: 1071941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering case AVAHI_ENTRY_GROUP_UNCOMMITED: 1072941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering /* Ignore */ 1073941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering break; 1074f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering 1075f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering case AVAHI_ENTRY_GROUP_FAILURE: 1076f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering /* Inform the user */ 1077f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering reg_report_error(sdref, map_error(avahi_client_errno(sdref->client))); 1078f17d2832301b0f2fcd50fdcc6fec77666178158fLennart Poettering break; 1079a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1080941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1081941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 1082941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1083941853354848fca4cc39bd72e6f34ca54443a9c8Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceRegister ( 1084e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering DNSServiceRef *ret_sdref, 1085e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering DNSServiceFlags flags, 1086e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering uint32_t interface, 1087a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering const char *name, 1088e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering const char *regtype, 1089a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering const char *domain, 1090a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering const char *host, 1091e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering uint16_t port, 1092e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering uint16_t txtLen, 1093a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering const void *txtRecord, 1094a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering DNSServiceRegisterReply callback, 1095e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering void *context) { 1096941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1097941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 1098941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering int error; 1099941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRef sdref = NULL; 110020011324500a728851e4888c890a756ecf71394bLennart Poettering AvahiStringList *txt = NULL; 1101e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering struct type_info type_info; 1102941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1103941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering AVAHI_WARN_LINKAGE; 1104941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1105511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!ret_sdref || !regtype) 1106c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd return kDNSServiceErr_BadParam; 1107c9109b4b6f4eca16ad867d91bd6683ac6355be76Trent Lloyd *ret_sdref = NULL; 1108a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1109511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering if (!txtRecord) { 1110511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering txtLen = 1; 1111511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering txtRecord = ""; 1112511bbee5e4da8e71b5da8521a162941398ebfdbaLennart Poettering } 1113941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 11141c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering if (interface == kDNSServiceInterfaceIndexLocalOnly || flags) { 11151c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering AVAHI_WARN_UNSUPPORTED; 1116941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unsupported; 11171c22aa6ce3490c7f5447179b4ec2e6113881660eLennart Poettering } 1118941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1119a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering if (txtLen > 0) 112020011324500a728851e4888c890a756ecf71394bLennart Poettering if (avahi_string_list_parse(txtRecord, txtLen, &txt) < 0) 112120011324500a728851e4888c890a756ecf71394bLennart Poettering return kDNSServiceErr_Invalid; 1122e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering 1123e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering if (type_info_parse(&type_info, regtype) < 0) { 1124e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering avahi_string_list_free(txt); 1125e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering return kDNSServiceErr_Invalid; 1126e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering } 1127a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 112820011324500a728851e4888c890a756ecf71394bLennart Poettering if (!(sdref = sdref_new())) { 112920011324500a728851e4888c890a756ecf71394bLennart Poettering avahi_string_list_free(txt); 1130e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering type_info_free(&type_info); 1131941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return kDNSServiceErr_Unknown; 113220011324500a728851e4888c890a756ecf71394bLennart Poettering } 1133941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1134941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->context = context; 1135941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_register_callback = callback; 1136941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1137e521a9a2fad8314d5e7d5bbde47b2c852a1426a7Lennart Poettering sdref->type_info = type_info; 1138941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_name = avahi_strdup(name); 1139d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering sdref->service_domain = domain ? avahi_normalize_name_strdup(domain) : NULL; 1140d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering sdref->service_host = host ? avahi_normalize_name_strdup(host) : NULL; 1141941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_interface = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface; 1142941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering sdref->service_port = ntohs(port); 114320011324500a728851e4888c890a756ecf71394bLennart Poettering sdref->service_txt = txt; 1144fee238b3a20c8fbb34af6b08995df2265131bee6Lennart Poettering 1145fee238b3a20c8fbb34af6b08995df2265131bee6Lennart Poettering /* Some OOM checking would be cool here */ 1146a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1147941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 1148a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 11496ecd227ceadc32ed229246aa61df6361c7b58a95Lennart Poettering if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, reg_client_callback, sdref, &error))) { 1150941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(error); 1151941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1152941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1153941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1154941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!sdref->service_domain) { 1155941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *d; 1156941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1157941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(d = avahi_client_get_domain_name(sdref->client))) { 1158941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 1159941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1160941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1161941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1162941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->service_domain = avahi_strdup(d))) { 1163941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoMemory; 1164941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1165941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1166941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1167941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1168941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->entry_group = avahi_entry_group_new(sdref->client, reg_entry_group_callback, sdref))) { 1169941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 1170941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1171941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1172941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1173941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (avahi_client_get_state(sdref->client) == AVAHI_CLIENT_S_RUNNING) { 1174941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering const char *n; 1175941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1176941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (sdref->service_name) 1177941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering n = sdref->service_name; 1178941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering else { 1179941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(n = avahi_client_get_host_name(sdref->client))) { 1180941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 1181941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1182941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1183941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1184941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1185941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (!(sdref->service_name_chosen = avahi_strdup(n))) { 1186941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoMemory; 1187941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1188941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1189941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1190a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1191941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if ((error = reg_create_service(sdref)) < 0) { 1192941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = map_error(error); 1193941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering goto finish; 1194941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1195941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering } 1196a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1197941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ret = kDNSServiceErr_NoError; 1198941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering *ret_sdref = sdref; 1199a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1200941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poetteringfinish: 1201941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1202941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 1203a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1204941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering if (ret != kDNSServiceErr_NoError) 1205941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering DNSServiceRefDeallocate(sdref); 1206941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1207941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering return ret; 1208941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering} 1209941853354848fca4cc39bd72e6f34ca54443a9c8Lennart Poettering 1210fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceUpdateRecord( 1211fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering DNSServiceRef sdref, 1212a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering DNSRecordRef rref, 1213fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering DNSServiceFlags flags, 1214fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering uint16_t rdlen, 1215fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering const void *rdata, 1216fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering AVAHI_GCC_UNUSED uint32_t ttl) { 1217fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1218fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering int ret = kDNSServiceErr_Unknown; 1219fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering AvahiStringList *txt = NULL; 1220fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1221fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering AVAHI_WARN_LINKAGE; 1222fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 12235b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering if (!sdref || sdref->n_ref <= 0) 12245b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering return kDNSServiceErr_BadParam; 12255b7e4f49787da905b9ec7d01eaf76462ca3a6e28Lennart Poettering 1226fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering if (flags || rref) { 1227fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering AVAHI_WARN_UNSUPPORTED; 1228fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering return kDNSServiceErr_Unsupported; 1229fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering } 1230fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1231a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering if (rdlen > 0) 1232fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering if (avahi_string_list_parse(rdata, rdlen, &txt) < 0) 1233fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering return kDNSServiceErr_Invalid; 1234fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1235fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 1236fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1237fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering if (!avahi_string_list_equal(txt, sdref->service_txt)) { 1238fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1239fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering avahi_string_list_free(sdref->service_txt); 1240fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->service_txt = txt; 1241fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1242fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering if (avahi_client_get_state(sdref->client) == AVAHI_CLIENT_S_RUNNING && 1243fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->entry_group && 1244fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering (avahi_entry_group_get_state(sdref->entry_group) == AVAHI_ENTRY_GROUP_ESTABLISHED || 1245fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering avahi_entry_group_get_state(sdref->entry_group) == AVAHI_ENTRY_GROUP_REGISTERING)) 1246fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1247fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering if (avahi_entry_group_update_service_txt_strlst( 1248fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->entry_group, 1249fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->service_interface, 1250fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering AVAHI_PROTO_UNSPEC, 1251fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 0, 1252fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->service_name_chosen, 1253fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->type_info.type, 1254fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->service_domain, 1255fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering sdref->service_txt) < 0) { 1256a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1257fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 1258fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering goto finish; 1259fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering } 1260fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1261fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering } else 1262fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering avahi_string_list_free(txt); 1263fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1264fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering ret = kDNSServiceErr_NoError; 1265a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1266fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poetteringfinish: 1267fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 1268a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1269fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering return ret; 1270fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering} 1271fc3830c24fd0341d762a2c4f05198f27fc3ccac0Lennart Poettering 1272e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poetteringstatic void query_resolver_callback( 1273e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AvahiRecordBrowser *r, 1274e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AvahiIfIndex interface, 1275e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AVAHI_GCC_UNUSED AvahiProtocol protocol, 1276e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AvahiBrowserEvent event, 1277e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering const char *name, 1278e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering uint16_t clazz, 1279e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering uint16_t type, 1280e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering const void* rdata, 1281e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering size_t size, 1282e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, 1283e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering void *userdata) { 1284e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1285e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceRef sdref = userdata; 1286e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1287e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering assert(r); 1288e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering assert(sdref); 1289e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering assert(sdref->n_ref >= 1); 1290e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1291e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering switch (event) { 1292e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1293e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering case AVAHI_BROWSER_NEW: 1294e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering case AVAHI_BROWSER_REMOVE: { 1295e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1296e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceFlags qflags = 0; 1297e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (event == AVAHI_BROWSER_NEW) 1298e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering qflags |= kDNSServiceFlagsAdd; 1299e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1300e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering sdref->query_resolver_callback(sdref, qflags, interface, kDNSServiceErr_NoError, name, type, clazz, size, rdata, 0, sdref->context); 1301e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering break; 1302e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering } 1303e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1304e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering case AVAHI_BROWSER_ALL_FOR_NOW: 1305e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering case AVAHI_BROWSER_CACHE_EXHAUSTED: 1306e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering /* not implemented */ 1307e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering break; 1308e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1309e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering case AVAHI_BROWSER_FAILURE: 1310e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering sdref->query_resolver_callback(sdref, 0, interface, map_error(avahi_client_errno(sdref->client)), NULL, 0, 0, 0, NULL, 0, sdref->context); 1311e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering break; 1312e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering } 1313e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering} 1314e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1315e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart PoetteringDNSServiceErrorType DNSSD_API DNSServiceQueryRecord ( 1316e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceRef *ret_sdref, 1317e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceFlags flags, 1318e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering uint32_t interface, 1319e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering const char *fullname, 1320e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering uint16_t type, 1321e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering uint16_t clazz, 1322e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceQueryRecordReply callback, 1323e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering void *context) { 1324e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1325e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceErrorType ret = kDNSServiceErr_Unknown; 1326e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering int error; 1327e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceRef sdref = NULL; 1328e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AvahiIfIndex ifindex; 1329e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1330e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AVAHI_WARN_LINKAGE; 1331e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1332e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (!ret_sdref || !fullname) 1333e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering return kDNSServiceErr_BadParam; 1334e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering *ret_sdref = NULL; 1335e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1336e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (interface == kDNSServiceInterfaceIndexLocalOnly || flags != 0) { 1337e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering AVAHI_WARN_UNSUPPORTED; 1338e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering return kDNSServiceErr_Unsupported; 1339e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering } 1340e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1341e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (!(sdref = sdref_new())) 1342e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering return kDNSServiceErr_Unknown; 1343e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1344e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering sdref->context = context; 1345e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering sdref->query_resolver_callback = callback; 1346e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1347e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ASSERT_SUCCESS(pthread_mutex_lock(&sdref->mutex)); 1348e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1349e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (!(sdref->client = avahi_client_new(avahi_simple_poll_get(sdref->simple_poll), 0, generic_client_callback, sdref, &error))) { 1350e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ret = map_error(error); 1351e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering goto finish; 1352e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering } 1353e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1354e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ifindex = interface == kDNSServiceInterfaceIndexAny ? AVAHI_IF_UNSPEC : (AvahiIfIndex) interface; 1355e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1356e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (!(sdref->record_browser = avahi_record_browser_new(sdref->client, ifindex, AVAHI_PROTO_UNSPEC, fullname, clazz, type, 0, query_resolver_callback, sdref))) { 1357e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ret = map_error(avahi_client_errno(sdref->client)); 1358e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering goto finish; 1359e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering } 1360e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1361e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ret = kDNSServiceErr_NoError; 1362e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering *ret_sdref = sdref; 1363e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1364e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poetteringfinish: 1365e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1366e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering ASSERT_SUCCESS(pthread_mutex_unlock(&sdref->mutex)); 1367e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1368e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering if (ret != kDNSServiceErr_NoError) 1369e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering DNSServiceRefDeallocate(sdref); 1370e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering 1371e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering return ret; 1372e31663c4a2fb2f8bf22efc237c3092242cc9bac2Lennart Poettering} 1373