]> git.meshlink.io Git - catta/blob - examples/client-browse-services.c
fix logic of AVAHI_SERVER_REGISTERING state handling. Many clients assumed that
[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-client/lookup.h>
33
34 #include <avahi-common/simple-watch.h>
35 #include <avahi-common/malloc.h>
36 #include <avahi-common/error.h>
37
38 static AvahiSimplePoll *simple_poll = NULL;
39
40 static void resolve_callback(
41     AvahiServiceResolver *r,
42     AVAHI_GCC_UNUSED AvahiIfIndex interface,
43     AVAHI_GCC_UNUSED AvahiProtocol protocol,
44     AvahiResolverEvent event,
45     const char *name,
46     const char *type,
47     const char *domain,
48     const char *host_name,
49     const AvahiAddress *address,
50     uint16_t port,
51     AvahiStringList *txt,
52     AvahiLookupResultFlags flags,
53     AVAHI_GCC_UNUSED void* userdata) {
54
55     assert(r);
56
57     /* Called whenever a service has been resolved successfully or timed out */
58
59     switch (event) {
60         case AVAHI_RESOLVER_FAILURE:
61             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))));
62             break;
63
64         case AVAHI_RESOLVER_FOUND: {
65             char a[AVAHI_ADDRESS_STR_MAX], *t;
66             
67             fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
68             
69             avahi_address_snprint(a, sizeof(a), address);
70             t = avahi_string_list_to_string(txt);
71             fprintf(stderr,
72                     "\t%s:%u (%s)\n"
73                     "\tTXT=%s\n"
74                     "\tcookie is %u\n"
75                     "\tis_local: %i\n"
76                     "\tour_own: %i\n"
77                     "\twide_area: %i\n"
78                     "\tmulticast: %i\n"
79                     "\tcached: %i\n",
80                     host_name, port, a,
81                     t,
82                     avahi_string_list_get_service_cookie(txt),
83                     !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
84                     !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
85                     !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
86                     !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
87                     !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
88                 
89             avahi_free(t);
90         }
91     }
92
93     avahi_service_resolver_free(r);
94 }
95
96 static void browse_callback(
97     AvahiServiceBrowser *b,
98     AvahiIfIndex interface,
99     AvahiProtocol protocol,
100     AvahiBrowserEvent event,
101     const char *name,
102     const char *type,
103     const char *domain,
104     AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
105     void* userdata) {
106     
107     AvahiClient *c = userdata;
108     assert(b);
109
110     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
111
112     switch (event) {
113         case AVAHI_BROWSER_FAILURE:
114             
115             fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
116             avahi_simple_poll_quit(simple_poll);
117             return;
118
119         case AVAHI_BROWSER_NEW:
120             fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
121
122             /* We ignore the returned resolver object. In the callback
123                function we free it. If the server is terminated before
124                the callback function is called the server will free
125                the resolver for us. */
126
127             if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c)))
128                 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
129             
130             break;
131
132         case AVAHI_BROWSER_REMOVE:
133             fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
134             break;
135
136         case AVAHI_BROWSER_ALL_FOR_NOW:
137         case AVAHI_BROWSER_CACHE_EXHAUSTED:
138             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
139             break;
140     }
141 }
142
143 static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
144     assert(c);
145
146     /* Called whenever the client or server state changes */
147
148     if (state == AVAHI_CLIENT_FAILURE) {
149         fprintf(stderr, "Server connection failre: %s\n", avahi_strerror(avahi_client_errno(c)));
150         avahi_simple_poll_quit(simple_poll);
151     }
152 }
153
154 int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
155     AvahiClient *client = NULL;
156     AvahiServiceBrowser *sb = NULL;
157     int error;
158     int ret = 1;
159
160     /* Allocate main loop object */
161     if (!(simple_poll = avahi_simple_poll_new())) {
162         fprintf(stderr, "Failed to create simple poll object.\n");
163         goto fail;
164     }
165
166     /* Allocate a new client */
167     client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
168
169     /* Check wether creating the client object succeeded */
170     if (!client) {
171         fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
172         goto fail;
173     }
174     
175     /* Create the service browser */
176     if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, client))) {
177         fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
178         goto fail;
179     }
180
181     /* Run the main loop */
182     avahi_simple_poll_loop(simple_poll);
183     
184     ret = 0;
185     
186 fail:
187     
188     /* Cleanup things */
189     if (sb)
190         avahi_service_browser_free(sb);
191     
192     if (client)
193         avahi_client_free(client);
194
195     if (simple_poll)
196         avahi_simple_poll_free(simple_poll);
197
198     return ret;
199 }