]> git.meshlink.io Git - catta/blob - examples/client-browse-services.c
add rlist.h and llist.h to doxygen docs
[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_TIMEOUT:
59         case AVAHI_RESOLVER_NOT_FOUND:
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,
62                     event == AVAHI_RESOLVER_TIMEOUT ? "TIMEOUT" : (event == AVAHI_RESOLVER_NOT_FOUND ? "NOT_FOUND" : "FAILURE"));
63
64
65         case AVAHI_RESOLVER_FOUND: {
66             char a[128], *t;
67             
68             fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
69             
70             avahi_address_snprint(a, sizeof(a), address);
71             t = avahi_string_list_to_string(txt);
72             fprintf(stderr,
73                     "\t%s:%u (%s)\n"
74                     "\tTXT=%s\n"
75                     "\tcookie is %u\n"
76                     "\tis_local: %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                     avahi_client_is_service_local(avahi_service_resolver_get_client(r), interface, protocol, name, type, domain),
84                     !!(flags & AVAHI_LOOKUP_CALLBACK_WIDE_AREA),
85                     !!(flags & AVAHI_LOOKUP_CALLBACK_MULTICAST),
86                     !!(flags & AVAHI_LOOKUP_CALLBACK_CACHED));
87                 
88             avahi_free(t);
89         }
90     }
91
92     avahi_service_resolver_free(r);
93 }
94
95 static void browse_callback(
96     AvahiServiceBrowser *b,
97     AvahiIfIndex interface,
98     AvahiProtocol protocol,
99     AvahiBrowserEvent event,
100     const char *name,
101     const char *type,
102     const char *domain,
103     AvahiLookupResultFlags flags,
104     void* userdata) {
105     
106     AvahiClient *c = userdata;
107     assert(b);
108
109     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
110
111     switch (event) {
112         case AVAHI_BROWSER_FAILURE:
113         case AVAHI_BROWSER_NOT_FOUND:
114             
115             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_FAILURE ? "FAILURE" : "NOT_FOUND");
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
144 static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) {
145     assert(c);
146
147     /* Called whenever the client or server state changes */
148
149     if (state == AVAHI_CLIENT_DISCONNECTED) {
150         fprintf(stderr, "Server connection terminated.\n");
151         avahi_simple_poll_quit(simple_poll);
152     }
153 }
154
155 int main(int argc, char*argv[]) {
156     AvahiClient *client = NULL;
157     AvahiServiceBrowser *sb = NULL;
158     int error;
159     int ret = 1;
160
161     /* Allocate main loop object */
162     if (!(simple_poll = avahi_simple_poll_new())) {
163         fprintf(stderr, "Failed to create simple poll object.\n");
164         goto fail;
165     }
166
167     /* Allocate a new client */
168     client = avahi_client_new(avahi_simple_poll_get(simple_poll), client_callback, NULL, &error);
169
170     /* Check wether creating the client object succeeded */
171     if (!client) {
172         fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
173         goto fail;
174     }
175     
176     /* Create the service browser */
177     if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, client))) {
178         fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
179         goto fail;
180     }
181     
182     /* Run the main loop */
183     for (;;)
184         if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
185             break;
186     
187     ret = 0;
188     
189 fail:
190     
191     /* Cleanup things */
192     if (sb)
193         avahi_service_browser_free(sb);
194     
195     if (client)
196         avahi_client_free(client);
197
198     if (simple_poll)
199         avahi_simple_poll_free(simple_poll);
200
201     return ret;
202 }