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