File: | build-analysis/../src/plugins/daap/daap_mdns_avahi.c |
Warning: | line 274, column 2 Function call argument is an uninitialized value |
1 | /** @file daap_mdns_browse.c | |||
2 | * Browser for DAAP servers shared via mDNS. | |||
3 | * | |||
4 | * Copyright (C) 2006-2017 XMMS2 Team | |||
5 | * | |||
6 | * This program is free software; you can redistribute it and/or | |||
7 | * modify it under the terms of the GNU General Public License | |||
8 | * as published by the Free Software Foundation; either version 2 | |||
9 | * of the License, or (at your option) any later version. | |||
10 | * | |||
11 | * This program is distributed in the hope that it will be useful, | |||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
14 | * GNU General Public License for more details. | |||
15 | */ | |||
16 | ||||
17 | #include "daap_mdns_browse.h" | |||
18 | ||||
19 | #include <xmms/xmms_log.h> | |||
20 | ||||
21 | #include <string.h> | |||
22 | #include <glib.h> | |||
23 | ||||
24 | #include <avahi-client/client.h> | |||
25 | #include <avahi-client/lookup.h> | |||
26 | ||||
27 | #include <avahi-common/malloc.h> | |||
28 | #include <avahi-common/error.h> | |||
29 | #include <avahi-common/timeval.h> | |||
30 | ||||
31 | #include <avahi-glib/glib-watch.h> | |||
32 | #include <avahi-glib/glib-malloc.h> | |||
33 | ||||
34 | #define ADDR_LEN(3 * 4 + 3 + 1) (3 * 4 + 3 + 1) /* standard dotted-quad fmt */ | |||
35 | ||||
36 | typedef struct { | |||
37 | AvahiClient *client; | |||
38 | GMainLoop *mainloop; | |||
39 | } browse_callback_userdata_t; | |||
40 | ||||
41 | static GSList *g_server_list = NULL((void*)0); | |||
42 | G_LOCK_DEFINE_STATIC (serv_list_mut)static GMutex g__serv_list_mut_lock; | |||
43 | static AvahiGLibPoll *gl_poll = NULL((void*)0); | |||
44 | static AvahiClient *client = NULL((void*)0); | |||
45 | static AvahiServiceBrowser *browser = NULL((void*)0); | |||
46 | ||||
47 | static GSList * | |||
48 | daap_mdns_serv_remove (GSList *serv_list, gchar *addr, guint port) | |||
49 | { | |||
50 | GSList *first = serv_list; | |||
51 | daap_mdns_server_t *serv; | |||
52 | ||||
53 | for ( ; serv_list != NULL((void*)0); serv_list = g_slist_next (serv_list)((serv_list) ? (((GSList *)(serv_list))->next) : ((void*)0 ))) { | |||
54 | serv = (daap_mdns_server_t *) serv_list->data; | |||
55 | if ( (port == serv->port) && (!strcmp (addr, serv->address)) ) { | |||
56 | serv_list = g_slist_remove (first, serv); | |||
57 | ||||
58 | g_free (serv->server_name); | |||
59 | g_free (serv->mdns_hostname); | |||
60 | g_free (serv->address); | |||
61 | g_free (serv); | |||
62 | ||||
63 | return serv_list; | |||
64 | } | |||
65 | } | |||
66 | return NULL((void*)0); | |||
67 | } | |||
68 | ||||
69 | static void | |||
70 | daap_mdns_resolve_browser_new_cb ( | |||
71 | AvahiServiceResolver *resolv, | |||
72 | AvahiIfIndex iface, | |||
73 | AvahiProtocol proto, | |||
74 | AvahiResolverEvent event, | |||
75 | const gchar *name, | |||
76 | const gchar *type, | |||
77 | const gchar *domain, | |||
78 | const gchar *hostname, | |||
79 | const AvahiAddress *addr, | |||
80 | guint16 port, | |||
81 | AvahiStringList *text, | |||
82 | AvahiLookupResultFlags flags, | |||
83 | void *userdata) | |||
84 | { | |||
85 | gchar ad[ADDR_LEN(3 * 4 + 3 + 1)]; | |||
86 | daap_mdns_server_t *server; | |||
87 | ||||
88 | if (!resolv) { | |||
89 | return; | |||
90 | } | |||
91 | ||||
92 | switch (event) { | |||
93 | case AVAHI_RESOLVER_FOUND: | |||
94 | avahi_address_snprint (ad, sizeof (ad), addr); | |||
95 | ||||
96 | server = g_new0 (daap_mdns_server_t, 1)((daap_mdns_server_t *) g_malloc0_n ((1), sizeof (daap_mdns_server_t ))); | |||
97 | server->server_name = g_strdup (name); | |||
98 | server->address = g_strdup (ad); | |||
99 | server->mdns_hostname = g_strdup (hostname); | |||
100 | server->port = port; | |||
101 | ||||
102 | G_LOCK (serv_list_mut)g_mutex_lock (&g__serv_list_mut_lock); | |||
103 | g_server_list = g_slist_prepend (g_server_list, server); | |||
104 | G_UNLOCK (serv_list_mut)g_mutex_unlock (&g__serv_list_mut_lock); | |||
105 | break; | |||
106 | ||||
107 | case AVAHI_RESOLVER_FAILURE: | |||
108 | break; | |||
109 | ||||
110 | default: | |||
111 | break; | |||
112 | } | |||
113 | ||||
114 | avahi_service_resolver_free (resolv); | |||
115 | } | |||
116 | ||||
117 | static void | |||
118 | daap_mdns_resolve_browser_remove_cb ( | |||
119 | AvahiServiceResolver *resolv, | |||
120 | AvahiIfIndex iface, | |||
121 | AvahiProtocol proto, | |||
122 | AvahiResolverEvent event, | |||
123 | const gchar *name, | |||
124 | const gchar *type, | |||
125 | const gchar *domain, | |||
126 | const gchar *hostname, | |||
127 | const AvahiAddress *addr, | |||
128 | guint16 port, | |||
129 | AvahiStringList *text, | |||
130 | AvahiLookupResultFlags flags, | |||
131 | void *userdata) | |||
132 | { | |||
133 | gchar ad[ADDR_LEN(3 * 4 + 3 + 1)]; | |||
134 | ||||
135 | if (!resolv) { | |||
136 | return; | |||
137 | } | |||
138 | ||||
139 | switch (event) { | |||
140 | case AVAHI_RESOLVER_FOUND: | |||
141 | avahi_address_snprint (ad, sizeof (ad), addr); | |||
142 | ||||
143 | G_LOCK (serv_list_mut)g_mutex_lock (&g__serv_list_mut_lock); | |||
144 | g_server_list = daap_mdns_serv_remove (g_server_list, ad, port); | |||
145 | G_UNLOCK (serv_list_mut)g_mutex_unlock (&g__serv_list_mut_lock); | |||
146 | break; | |||
147 | ||||
148 | case AVAHI_RESOLVER_FAILURE: | |||
149 | break; | |||
150 | ||||
151 | default: | |||
152 | break; | |||
153 | } | |||
154 | ||||
155 | avahi_service_resolver_free (resolv); | |||
156 | } | |||
157 | ||||
158 | static void | |||
159 | daap_mdns_browse_cb (AvahiServiceBrowser *browser, | |||
160 | AvahiIfIndex iface, | |||
161 | AvahiProtocol proto, | |||
162 | AvahiBrowserEvent event, | |||
163 | const gchar *name, | |||
164 | const gchar *type, | |||
165 | const gchar *domain, | |||
166 | AvahiLookupResultFlags flags, | |||
167 | void *userdata) | |||
168 | { | |||
169 | AvahiClient *client = ((browse_callback_userdata_t *) userdata)->client; | |||
170 | ||||
171 | if (!browser) { | |||
172 | return; | |||
173 | } | |||
174 | ||||
175 | switch (event) { | |||
176 | case AVAHI_BROWSER_NEW: | |||
177 | avahi_service_resolver_new (client, iface, proto, name, type, | |||
178 | domain, AVAHI_PROTO_UNSPEC, 0, | |||
179 | daap_mdns_resolve_browser_new_cb, NULL((void*)0)); | |||
180 | break; | |||
181 | ||||
182 | case AVAHI_BROWSER_REMOVE: | |||
183 | avahi_service_resolver_new (client, iface, proto, name, type, | |||
184 | domain, AVAHI_PROTO_UNSPEC, 0, | |||
185 | daap_mdns_resolve_browser_remove_cb, NULL((void*)0)); | |||
186 | break; | |||
187 | ||||
188 | case AVAHI_BROWSER_CACHE_EXHAUSTED: | |||
189 | break; | |||
190 | ||||
191 | case AVAHI_BROWSER_ALL_FOR_NOW: | |||
192 | break; | |||
193 | ||||
194 | default: | |||
195 | break; | |||
196 | } | |||
197 | } | |||
198 | ||||
199 | static void | |||
200 | daap_mdns_client_cb (AvahiClient *client, | |||
201 | AvahiClientState state, | |||
202 | void * userdata) | |||
203 | { | |||
204 | if (!client) { | |||
205 | return; | |||
206 | } | |||
207 | ||||
208 | switch (state) { | |||
209 | case AVAHI_CLIENT_FAILURE: | |||
210 | break; | |||
211 | default: | |||
212 | break; | |||
213 | } | |||
214 | } | |||
215 | ||||
216 | static void | |||
217 | daap_mdns_timeout (AvahiTimeout *to, void *userdata) | |||
218 | { | |||
219 | } | |||
220 | ||||
221 | gboolean | |||
222 | daap_mdns_setup () | |||
223 | { | |||
224 | const AvahiPoll *av_poll; | |||
225 | ||||
226 | GMainLoop *ml = NULL((void*)0); | |||
227 | gint errval; | |||
228 | struct timeval tv; | |||
229 | browse_callback_userdata_t *browse_userdata; | |||
| ||||
230 | ||||
231 | if (gl_poll) { | |||
232 | goto fail; | |||
233 | } | |||
234 | ||||
235 | browse_userdata = g_new0 (browse_callback_userdata_t, 1)((browse_callback_userdata_t *) g_malloc0_n ((1), sizeof (browse_callback_userdata_t ))); | |||
236 | ||||
237 | avahi_set_allocator (avahi_glib_allocator ()); | |||
238 | ||||
239 | ml = g_main_loop_new (NULL((void*)0), FALSE(0)); | |||
240 | ||||
241 | gl_poll = avahi_glib_poll_new (NULL((void*)0), G_PRIORITY_DEFAULT0); | |||
242 | av_poll = avahi_glib_poll_get (gl_poll); | |||
243 | ||||
244 | avahi_elapse_time (&tv, 2000, 0); | |||
245 | av_poll->timeout_new (av_poll, &tv, daap_mdns_timeout, NULL((void*)0)); | |||
246 | ||||
247 | client = avahi_client_new (av_poll, 0, daap_mdns_client_cb, ml, &errval); | |||
248 | if (!client) { | |||
249 | goto fail; | |||
250 | } | |||
251 | ||||
252 | browse_userdata->client = client; | |||
253 | browse_userdata->mainloop = ml; | |||
254 | ||||
255 | browser = avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | |||
256 | AVAHI_PROTO_UNSPEC, "_daap._tcp", NULL((void*)0), | |||
257 | 0, daap_mdns_browse_cb, | |||
258 | browse_userdata); | |||
259 | if (!browser) { | |||
260 | goto fail; | |||
261 | } | |||
262 | ||||
263 | return TRUE(!(0)); | |||
264 | ||||
265 | fail: | |||
266 | if (ml) | |||
267 | g_main_loop_unref (ml); | |||
268 | ||||
269 | if (client) | |||
270 | avahi_client_free (client); | |||
271 | client = NULL((void*)0); | |||
272 | browser = NULL((void*)0); | |||
273 | ||||
274 | g_free (browse_userdata); | |||
| ||||
275 | ||||
276 | if (gl_poll) | |||
277 | avahi_glib_poll_free (gl_poll); | |||
278 | gl_poll = NULL((void*)0); | |||
279 | ||||
280 | return FALSE(0); | |||
281 | } | |||
282 | ||||
283 | GSList * | |||
284 | daap_mdns_get_server_list () | |||
285 | { | |||
286 | GSList * l; | |||
287 | G_LOCK (serv_list_mut)g_mutex_lock (&g__serv_list_mut_lock); | |||
288 | l = g_slist_copy (g_server_list); | |||
289 | G_UNLOCK (serv_list_mut)g_mutex_unlock (&g__serv_list_mut_lock); | |||
290 | return l; | |||
291 | } | |||
292 | ||||
293 | void | |||
294 | daap_mdns_destroy () | |||
295 | { | |||
296 | /* FIXME: deinit avahi */ | |||
297 | } | |||
298 |