]> git.meshlink.io Git - catta/blob - examples/client-browse-services.c
Complete AVAHI_LOOKUP_NO_ADDRESS fix
[catta] / examples / client-browse-services.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <assert.h>
28 #include <stdlib.h>
29 #include <time.h>
30
31 #include <avahi-client/client.h>
32 #include <avahi-common/simple-watch.h>
33 #include <avahi-common/malloc.h>
34 #include <avahi-common/error.h>
35
36 static AvahiSimplePoll *simple_poll = NULL;
37
38 static void resolve_callback(
39     AvahiServiceResolver *r,
40     AvahiIfIndex interface,
41     AvahiProtocol protocol,
42     AvahiResolverEvent event,
43     const char *name,
44     const char *type,
45     const char *domain,
46     const char *host_name,
47     const AvahiAddress *address,
48     uint16_t port,
49     AvahiStringList *txt,
50     AvahiLookupResultFlags flags,
51     void* userdata) {
52
53     assert(r);
54
55     /* Called whenever a service has been resolved successfully or timed out */
56
57     switch (event) {
58         case AVAHI_RESOLVER_FAILURE:
59             fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
60             break;
61
62         case AVAHI_RESOLVER_FOUND: {
63             char a[128], *t;
64             
65             fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
66             
67             avahi_address_snprint(a, sizeof(a), address);
68             t = avahi_string_list_to_string(txt);
69             fprintf(stderr,
70                     "\t%s:%u (%s)\n"
71                     "\tTXT=%s\n"
72                     "\tcookie is %u\n"
73                     "\tis_local: %i\n"
74                     "\twide_area: %i\n"
75                     "\tmulticast: %i\n"
76                     "\tcached: %i\n",
77                     host_name, port, a,
78                     t,
79                     avahi_string_list_get_service_cookie(txt),
80                     avahi_client_is_service_local(avahi_service_resolver_get_client(r), interface, protocol, name, type, domain),
81                     !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
82                     !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
83                     !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
84                 
85             avahi_free(t);
86         }
87     }
88
89     avahi_service_resolver_free(r);
90 }
91
92 static void browse_callback(
93     AvahiServiceBrowser *b,
94     AvahiIfIndex interface,
95     AvahiProtocol protocol,
96     AvahiBrowserEvent event,
97     const char *name,
98     const char *type,
99     const char *domain,
100     AvahiLookupResultFlags flags,
101     void* userdata) {
102     
103     AvahiClient *c = userdata;
104     assert(b);
105
106     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
107
108     switch (event) {
109         case AVAHI_BROWSER_FAILURE:
110             
111             fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
112             avahi_simple_poll_quit(simple_poll);
113             return;
114
115         case AVAHI_BROWSER_NEW:
116             fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
117
118             /* We ignore the returned resolver object. In the callback
119                function we free it. If the server is terminated before
120                the callback function is called the server will free
121                the resolver for us. */
122
123             if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c)))
124                 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
125             
126             break;
127
128         case AVAHI_BROWSER_REMOVE:
129             fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
130             break;
131
132         case AVAHI_BROWSER_ALL_FOR_NOW:
133         case AVAHI_BROWSER_CACHE_EXHAUSTED:
134             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
135             break;
136
137     }
138 }
139
140 static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) {
141     assert(c);
142
143     /* Called whenever the client or server state changes */
144
145     if (state == AVAHI_CLIENT_DISCONNECTED) {
146         fprintf(stderr, "Server connection terminated.\n");
147         avahi_simple_poll_quit(simple_poll);
148     }
149 }
150
151 int main(int argc, char*argv[]) {
152     AvahiClient *client = NULL;
153     AvahiServiceBrowser *sb = NULL;
154     int error;
155     int ret = 1;
156
157     /* Allocate main loop object */
158     if (!(simple_poll = avahi_simple_poll_new())) {
159         fprintf(stderr, "Failed to create simple poll object.\n");
160         goto fail;
161     }
162
163     /* Allocate a new client */
164     client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error);
165
166     /* Check wether creating the client object succeeded */
167     if (!client) {
168         fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
169         goto fail;
170     }
171     
172     /* Create the service browser */
173     if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, client))) {
174         fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
175         goto fail;
176     }
177     
178     /* Run the main loop */
179     for (;;)
180         if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
181             break;
182     
183     ret = 0;
184     
185 fail:
186     
187     /* Cleanup things */
188     if (sb)
189         avahi_service_browser_free(sb);
190     
191     if (client)
192         avahi_client_free(client);
193
194     if (simple_poll)
195         avahi_simple_poll_free(simple_poll);
196
197     return ret;
198 }