1 --- /usr/tmp/clean/avahi-0.6.21/avahi-core/browse-service.c 2006-08-31 18:18:03.000000000 +0100 2 +++ avahi-0.6.21/avahi-core/browse-service.c 2007-09-20 10:19:21.368616000 +0100 3 @@ -23,10 +23,14 @@ 4 #include <config.h> 5 #endif 6 7 +#include <stdio.h> 8 #include <string.h> 9 10 #include <avahi-common/domain.h> 11 #include <avahi-common/malloc.h> 12 +#ifdef HAVE_BONJOUR 13 +#include <avahi-common/timeval.h> 14 +#endif 15 #include <avahi-common/error.h> 16 17 #include "browse.h" 18 @@ -42,9 +46,131 @@ 19 AvahiSServiceBrowserCallback callback; 20 void* userdata; 21 22 +#ifdef HAVE_BONJOUR 23 + AvahiProtocol protocol; 24 + AvahiIfIndex interface; 25 + AvahiTimeEvent *browse_error_event; 26 + AvahiTimeEvent *all_for_now_event; 27 + AvahiLookupFlags flags; 28 + AvahiWatch *watch; 29 + DNSServiceRef client; 30 +#endif 31 + 32 AVAHI_LLIST_FIELDS(AvahiSServiceBrowser, browser); 33 }; 34 35 +#ifdef HAVE_BONJOUR 36 +static void browse_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t IfIndex, DNSServiceErrorType errorCode, 37 + const char *name, const char *type, const char *domain, void *context) { 38 + AvahiSServiceBrowser *b = context; 39 + char *op = (flags &kDNSServiceFlagsAdd) ? "Add" : "Rmv"; 40 + AvahiBrowserEvent event; 41 + AvahiIfIndex interface; 42 + 43 + interface = (IfIndex == kDNSServiceInterfaceIndexAny) ? AVAHI_IF_UNSPEC : IfIndex; 44 + 45 + event = (flags &kDNSServiceFlagsAdd) ? AVAHI_BROWSER_NEW : AVAHI_BROWSER_REMOVE; 46 + 47 + b->callback(b, interface, AVAHI_PROTO_UNSPEC, event, name, type, domain, 0, b->userdata); 48 + 49 +} 50 + 51 +static void browse_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *userdata) { 52 + AvahiSServiceBrowser *b = userdata; 53 + DNSServiceErrorType ret; 54 + 55 + assert(w); 56 + assert(fd >= 0); 57 + assert(events & AVAHI_WATCH_IN); 58 + 59 + assert (fd == DNSServiceRefSockFD(b->client)); 60 + ret = DNSServiceProcessResult(b->client); 61 + if (ret != kDNSServiceErr_NoError) { 62 + if (b->watch) { 63 + b->server->poll_api->watch_free(b->watch); 64 + b->watch = NULL; 65 + } 66 + DNSServiceRefDeallocate(b->client); 67 + b->client = NULL; 68 + avahi_server_set_errno(b->server, AVAHI_ERR_DISCONNECTED); 69 + b->callback(b, 70 + b->interface, 71 + b->protocol, 72 + AVAHI_BROWSER_FAILURE, 73 + NULL, 74 + b->service_type, 75 + b->domain_name, 76 + 0, 77 + b->userdata); 78 + } 79 +} 80 + 81 +static void all_for_now_callback(AvahiTimeEvent *e, void* userdata) { 82 + AvahiSServiceBrowser *b = userdata; 83 + 84 + assert(e); 85 + assert(b); 86 + 87 + avahi_time_event_free(b->all_for_now_event); 88 + b->all_for_now_event = NULL; 89 + 90 + b->callback(b, 91 + b->interface, 92 + b->protocol, 93 + AVAHI_BROWSER_ALL_FOR_NOW, 94 + NULL, 95 + b->service_type, 96 + NULL, 97 + 0, 98 + b->userdata); 99 +} 100 + 101 +static void browse_error_callback(AvahiTimeEvent *e, void *userdata) { 102 + AvahiSServiceBrowser *b = userdata; 103 + 104 + if (b->browse_error_event) { 105 + avahi_time_event_free(b->browse_error_event); 106 + b->browse_error_event = NULL; 107 + } 108 + avahi_server_set_errno(b->server, AVAHI_ERR_FAILURE); 109 + b->callback(b, 110 + b->interface, 111 + b->protocol, 112 + AVAHI_BROWSER_FAILURE, 113 + NULL, 114 + b->service_type, 115 + b->domain_name, 116 + 0, 117 + b->userdata); 118 +} 119 + 120 +static void avahi_browse_service_start(AvahiSServiceBrowser *b) { 121 + DNSServiceErrorType ret; 122 + struct timeval tv; 123 + 124 + ret = DNSServiceBrowse(&b->client, 125 + 0, 126 + b->interface == AVAHI_IF_UNSPEC ? 127 + kDNSServiceInterfaceIndexAny : 128 + b->interface, 129 + b->service_type, 130 + b->domain_name, 131 + browse_reply, 132 + b); 133 + if (ret != kDNSServiceErr_NoError || !b->client) { 134 + b->browse_error_event = avahi_time_event_new(b->server->time_event_queue, 135 +NULL, browse_error_callback, b); 136 + } else { 137 + b->watch = b->server->poll_api->watch_new(b->server->poll_api, DNSServiceRefSockFD(b->client), AVAHI_WATCH_IN, browse_socket_event, b); 138 + 139 + /* Add a second */ 140 + gettimeofday(&tv, NULL); 141 + avahi_timeval_add(&tv, 1000000); 142 + b->all_for_now_event = avahi_time_event_new(b->server->time_event_queue, &tv, all_for_now_callback, b); 143 + } 144 +} 145 +#endif 146 + 147 static void record_browser_callback( 148 AvahiSRecordBrowser*rr, 149 AvahiIfIndex interface, 150 @@ -104,7 +230,11 @@ 151 AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); 152 AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); 153 AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); 154 +#ifdef HAVE_BONJOUR 155 + AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); 156 +#else 157 AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); 158 +#endif 159 AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_generic(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE); 160 161 if (!domain) 162 @@ -134,6 +264,16 @@ 163 goto fail; 164 } 165 166 +#ifdef HAVE_BONJOUR 167 + b->protocol = protocol; 168 + b->interface = interface; 169 + b->flags = flags; 170 + b->browse_error_event = NULL; 171 + b->all_for_now_event = NULL; 172 + b->client = NULL; 173 + b->watch = NULL; 174 + avahi_browse_service_start(b); 175 +#else 176 if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR))) { 177 avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY); 178 goto fail; 179 @@ -143,6 +283,7 @@ 180 goto fail; 181 182 avahi_key_unref(k); 183 +#endif 184 185 return b; 186 187 @@ -165,5 +306,21 @@ 188 189 avahi_free(b->domain_name); 190 avahi_free(b->service_type); 191 +#ifdef HAVE_BONJOUR 192 + if (b->browse_error_event) { 193 + avahi_time_event_free(b->browse_error_event); 194 + b->browse_error_event = NULL; 195 + } 196 + if (b->all_for_now_event) { 197 + avahi_time_event_free(b->all_for_now_event); 198 + b->all_for_now_event = NULL; 199 + } 200 + 201 + if (b->watch) 202 + b->server->poll_api->watch_free(b->watch); 203 + 204 + if (b->client) 205 + DNSServiceRefDeallocate (b->client); 206 +#endif 207 avahi_free(b); 208 } 209