]> git.meshlink.io Git - catta/blob - avahi-client/resolver.c
14d6acadee4d1178f2b57394880ccf2b16811510
[catta] / avahi-client / resolver.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 <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <dbus/dbus.h>
31
32 #include <avahi-client/client.h>
33 #include <avahi-common/dbus.h>
34 #include <avahi-common/llist.h>
35 #include <avahi-common/error.h>
36 #include <avahi-common/malloc.h>
37
38 #include "client.h"
39 #include "internal.h"
40
41 /* AvahiServiceResolver implementation */
42
43 DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) {
44     AvahiServiceResolver *r = NULL;
45     DBusError error;
46     const char *path;
47     AvahiStringList *strlst = NULL;
48
49     assert(client);
50     assert(message);
51     
52     dbus_error_init (&error);
53
54     if (!(path = dbus_message_get_path(message)))
55         goto fail;
56
57     for (r = client->service_resolvers; r; r = r->service_resolvers_next)
58         if (strcmp (r->path, path) == 0)
59             break;
60
61     if (!r)
62         goto fail;
63
64     switch (event) {
65         case AVAHI_RESOLVER_FOUND: {
66             int j;
67             int32_t interface, protocol, aprotocol;
68             uint32_t flags;
69             char *name, *type, *domain, *host, *address;
70             uint16_t port;
71             DBusMessageIter iter, sub;
72             AvahiAddress a;
73             
74             if (!dbus_message_get_args(
75                     message, &error,
76                     DBUS_TYPE_INT32, &interface,
77                     DBUS_TYPE_INT32, &protocol,
78                     DBUS_TYPE_STRING, &name,
79                     DBUS_TYPE_STRING, &type,
80                     DBUS_TYPE_STRING, &domain,
81                     DBUS_TYPE_STRING, &host,
82                     DBUS_TYPE_INT32, &aprotocol,
83                     DBUS_TYPE_STRING, &address,
84                     DBUS_TYPE_UINT16, &port,
85                     DBUS_TYPE_INVALID) ||
86                 dbus_error_is_set (&error)) {
87             
88                 fprintf(stderr, "Failed to parse resolver event.\n");
89                 goto fail;
90             }
91         
92             dbus_message_iter_init(message, &iter);
93         
94             for (j = 0; j < 9; j++)
95                 dbus_message_iter_next(&iter);
96         
97             if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
98                 dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) {
99                 fprintf(stderr, "Error parsing service resolving message\n");
100                 goto fail;
101             }
102         
103             strlst = NULL;
104             dbus_message_iter_recurse(&iter, &sub);
105         
106             for (;;) {
107                 DBusMessageIter sub2;
108                 int at;
109             
110                 if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID)
111                     break;
112             
113                 assert(at == DBUS_TYPE_ARRAY);
114             
115                 if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE) {
116                     fprintf(stderr, "Error parsing service resolving message\n");
117                     goto fail;
118                 }
119             
120                 dbus_message_iter_recurse(&sub, &sub2);
121
122                 if (dbus_message_iter_get_array_len(&sub2) > 0) {
123                     uint8_t *k;
124                     int n;
125                 
126                     dbus_message_iter_get_fixed_array(&sub2, &k, &n);
127                     strlst = avahi_string_list_add_arbitrary(strlst, k, n);
128                 }
129             
130                 dbus_message_iter_next(&sub);
131             }
132
133             dbus_message_iter_next(&iter);
134
135             if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
136                 fprintf(stderr, "Failed to parse resolver event.\n");
137                 goto fail;
138             }
139
140             dbus_message_iter_get_basic(&iter, &flags);
141                                     
142             assert(address);
143
144             if (address[0] == 0)
145                 address = NULL;
146             else
147                 avahi_address_parse(address, (AvahiProtocol) aprotocol, &a);
148     
149             r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, type, domain, host, address ? &a : NULL, port, strlst, (AvahiLookupResultFlags) flags, r->userdata);
150         
151             avahi_string_list_free(strlst);
152             break;
153         }
154             
155         case AVAHI_RESOLVER_FAILURE: {
156             char *etxt;
157             
158             if (!dbus_message_get_args(
159                     message, &error,
160                     DBUS_TYPE_STRING, &etxt,
161                     DBUS_TYPE_INVALID) ||
162                 dbus_error_is_set (&error)) {
163                 fprintf(stderr, "Failed to parse resolver event.\n");
164                 goto fail;
165             }
166             
167             avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
168             r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, r->userdata);
169             break;
170         }
171     }
172
173     return DBUS_HANDLER_RESULT_HANDLED;
174
175     
176 fail:
177     dbus_error_free (&error);
178     avahi_string_list_free(strlst);
179     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
180 }
181
182 AvahiServiceResolver * avahi_service_resolver_new(
183     AvahiClient *client,
184     AvahiIfIndex interface,
185     AvahiProtocol protocol,
186     const char *name,
187     const char *type,
188     const char *domain,
189     AvahiProtocol aprotocol,
190     AvahiLookupFlags flags,
191     AvahiServiceResolverCallback callback,
192     void *userdata) {
193
194     DBusError error;
195     AvahiServiceResolver *r = NULL;
196     DBusMessage *message = NULL, *reply = NULL;
197     int32_t i_interface, i_protocol, i_aprotocol;
198     uint32_t u_flags;
199     char *path;
200     
201     assert(client);
202     assert(type);
203
204     if (!domain)
205         domain = "";
206
207     if (!name)
208         name = "";
209     
210     dbus_error_init (&error);
211
212     if (client->state == AVAHI_CLIENT_DISCONNECTED) {
213         avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
214         goto fail;
215     }
216
217     if (!(r = avahi_new(AvahiServiceResolver, 1))) {
218         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
219         goto fail;
220     }
221
222     r->client = client;
223     r->callback = callback;
224     r->userdata = userdata;
225     r->path = NULL;
226     
227     AVAHI_LLIST_PREPEND(AvahiServiceResolver, service_resolvers, client->service_resolvers, r);
228
229     if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew"))) {
230         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
231         goto fail;
232     }
233
234     i_interface = (int32_t) interface;
235     i_protocol = (int32_t) protocol;
236     i_aprotocol = (int32_t) aprotocol;
237     u_flags = (uint32_t) flags;
238
239     if (!(dbus_message_append_args(
240               message,
241               DBUS_TYPE_INT32, &i_interface,
242               DBUS_TYPE_INT32, &i_protocol,
243               DBUS_TYPE_STRING, &name,
244               DBUS_TYPE_STRING, &type,
245               DBUS_TYPE_STRING, &domain,
246               DBUS_TYPE_INT32, &i_aprotocol,
247               DBUS_TYPE_UINT32, &u_flags,
248               DBUS_TYPE_INVALID))) {
249         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
250         goto fail;
251     }
252
253     if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) ||
254         dbus_error_is_set(&error)) {
255         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
256         goto fail;
257     }
258
259     if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
260         dbus_error_is_set(&error) ||
261         !path) {
262         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
263         goto fail;
264     }
265
266     if (!(r->path = avahi_strdup(path))) {
267
268         /* FIXME: We don't remove the object on the server side */
269
270         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
271         goto fail;
272     }
273         
274
275     dbus_message_unref(message);
276     dbus_message_unref(reply);
277
278     return r;
279     
280 fail:
281
282     if (dbus_error_is_set(&error)) {
283         avahi_client_set_dbus_error(client, &error);
284         dbus_error_free(&error);
285     }
286
287     if (r)
288         avahi_service_resolver_free(r);
289     
290     if (message)
291         dbus_message_unref(message);
292
293     if (reply)
294         dbus_message_unref(reply);
295     
296     return NULL;
297
298 }
299
300 AvahiClient* avahi_service_resolver_get_client (AvahiServiceResolver *r) {
301     assert (r);
302
303     return r->client;
304 }
305
306 int avahi_service_resolver_free(AvahiServiceResolver *r) {
307     AvahiClient *client;
308     int ret = AVAHI_OK;
309
310     assert(r);
311     client = r->client;
312
313     if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED)
314         ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free");
315
316     AVAHI_LLIST_REMOVE(AvahiServiceResolver, service_resolvers, client->service_resolvers, r);
317
318     avahi_free(r->path);
319     avahi_free(r);
320
321     return ret;
322 }
323
324 /* AvahiHostNameResolver implementation */
325
326 DBusHandlerResult avahi_host_name_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) {
327     AvahiHostNameResolver *r = NULL;
328     DBusError error;
329     const char *path;
330
331     assert(client);
332     assert(message);
333     
334     dbus_error_init (&error);
335
336     if (!(path = dbus_message_get_path(message)))
337         goto fail;
338
339     for (r = client->host_name_resolvers; r; r = r->host_name_resolvers_next)
340         if (strcmp (r->path, path) == 0)
341             break;
342
343     if (!r)
344         goto fail;
345
346     switch (event) {
347         case AVAHI_RESOLVER_FOUND: {
348             int32_t interface, protocol, aprotocol;
349             uint32_t flags;
350             char *name, *address;
351             AvahiAddress a;
352             
353             if (!dbus_message_get_args(
354                     message, &error,
355                     DBUS_TYPE_INT32, &interface,
356                     DBUS_TYPE_INT32, &protocol,
357                     DBUS_TYPE_STRING, &name,
358                     DBUS_TYPE_INT32, &aprotocol,
359                     DBUS_TYPE_STRING, &address,
360                     DBUS_TYPE_UINT32, &flags,
361                     DBUS_TYPE_INVALID) ||
362                 dbus_error_is_set (&error)) {
363                 fprintf(stderr, "Failed to parse resolver event.\n");
364                 goto fail;
365             }
366             
367             assert(address);
368             if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) {
369                 fprintf(stderr, "Failed to parse address\n");
370                 goto fail;
371             }
372             
373             r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, &a, (AvahiLookupResultFlags) flags, r->userdata);
374             break;
375         }
376             
377         case AVAHI_RESOLVER_FAILURE: {
378             char *etxt;
379             
380             if (!dbus_message_get_args(
381                     message, &error,
382                     DBUS_TYPE_STRING, &etxt,
383                     DBUS_TYPE_INVALID) ||
384                 dbus_error_is_set (&error)) {
385                 fprintf(stderr, "Failed to parse resolver event.\n");
386                 goto fail;
387             }
388             
389             avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
390             r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, NULL, 0, r->userdata);
391             break;
392         }
393     }
394
395     return DBUS_HANDLER_RESULT_HANDLED;
396     
397 fail:
398     dbus_error_free (&error);
399     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
400 }
401
402
403 AvahiHostNameResolver * avahi_host_name_resolver_new(
404     AvahiClient *client,
405     AvahiIfIndex interface,
406     AvahiProtocol protocol,
407     const char *name,
408     AvahiProtocol aprotocol,
409     AvahiLookupFlags flags,
410     AvahiHostNameResolverCallback callback,
411     void *userdata) {
412
413     DBusError error;
414     AvahiHostNameResolver *r = NULL;
415     DBusMessage *message = NULL, *reply = NULL;
416     int32_t i_interface, i_protocol, i_aprotocol;
417     uint32_t u_flags;
418     char *path;
419     
420     assert(client);
421     assert(name);
422
423     dbus_error_init (&error);
424
425     if (client->state == AVAHI_CLIENT_DISCONNECTED) {
426         avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
427         goto fail;
428     }
429
430     if (!(r = avahi_new(AvahiHostNameResolver, 1))) {
431         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
432         goto fail;
433     }
434
435     r->client = client;
436     r->callback = callback;
437     r->userdata = userdata;
438     r->path = NULL;
439     
440     AVAHI_LLIST_PREPEND(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r);
441
442     if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew"))) {
443         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
444         goto fail;
445     }
446
447     i_interface = (int32_t) interface;
448     i_protocol = (int32_t) protocol;
449     i_aprotocol = (int32_t) aprotocol;
450     u_flags = (uint32_t) flags;
451
452     if (!(dbus_message_append_args(
453               message,
454               DBUS_TYPE_INT32, &i_interface,
455               DBUS_TYPE_INT32, &i_protocol,
456               DBUS_TYPE_STRING, &name,
457               DBUS_TYPE_INT32, &i_aprotocol,
458               DBUS_TYPE_UINT32, &u_flags,
459               DBUS_TYPE_INVALID))) {
460         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
461         goto fail;
462     }
463
464     if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) ||
465         dbus_error_is_set(&error)) {
466         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
467         goto fail;
468     }
469
470     if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
471         dbus_error_is_set(&error) ||
472         !path) {
473         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
474         goto fail;
475     }
476
477     if (!(r->path = avahi_strdup(path))) {
478
479         /* FIXME: We don't remove the object on the server side */
480
481         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
482         goto fail;
483     }
484
485     dbus_message_unref(message);
486     dbus_message_unref(reply);
487
488     return r;
489     
490 fail:
491
492     if (dbus_error_is_set(&error)) {
493         avahi_client_set_dbus_error(client, &error);
494         dbus_error_free(&error);
495     }
496
497     if (r)
498         avahi_host_name_resolver_free(r);
499     
500     if (message)
501         dbus_message_unref(message);
502
503     if (reply)
504         dbus_message_unref(reply);
505
506     return NULL;
507
508 }
509
510 int avahi_host_name_resolver_free(AvahiHostNameResolver *r) {
511     int ret = AVAHI_OK;
512     AvahiClient *client;
513
514     assert(r);
515     client = r->client;
516
517     if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED)
518         ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free");
519
520     AVAHI_LLIST_REMOVE(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r);
521
522     avahi_free(r->path);
523     avahi_free(r);
524
525     return ret;
526 }
527
528 AvahiClient* avahi_host_name_resolver_get_client (AvahiHostNameResolver *r) {
529     assert (r);
530
531     return r->client;
532 }
533
534 /* AvahiAddressResolver implementation */
535
536 DBusHandlerResult avahi_address_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) {
537     AvahiAddressResolver *r = NULL;
538     DBusError error;
539     const char *path;
540
541     assert(client);
542     assert(message);
543     
544     dbus_error_init (&error);
545
546     if (!(path = dbus_message_get_path(message)))
547         goto fail;
548
549     for (r = client->address_resolvers; r; r = r->address_resolvers_next)
550         if (strcmp (r->path, path) == 0)
551             break;
552
553     if (!r)
554         goto fail;
555
556     switch (event) {
557         case AVAHI_RESOLVER_FOUND: {
558             int32_t interface, protocol, aprotocol;
559             uint32_t flags;
560             char *name, *address;
561             AvahiAddress a;
562             
563             if (!dbus_message_get_args(
564                     message, &error,
565                     DBUS_TYPE_INT32, &interface,
566                     DBUS_TYPE_INT32, &protocol,
567                     DBUS_TYPE_INT32, &aprotocol,
568                     DBUS_TYPE_STRING, &address,
569                     DBUS_TYPE_STRING, &name,
570                     DBUS_TYPE_UINT32, &flags,
571                     DBUS_TYPE_INVALID) ||
572                 dbus_error_is_set (&error)) {
573                 fprintf(stderr, "Failed to parse resolver event.\n");
574                 goto fail;
575             }
576             
577             assert(address);
578             if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) {
579                 fprintf(stderr, "Failed to parse address\n");
580                 goto fail;
581             }
582             
583             r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, (AvahiProtocol) aprotocol, &a, name, (AvahiLookupResultFlags) flags, r->userdata);
584             break;
585         }
586
587         case AVAHI_RESOLVER_FAILURE: {
588             char *etxt;
589             
590             if (!dbus_message_get_args(
591                     message, &error,
592                     DBUS_TYPE_STRING, &etxt,
593                     DBUS_TYPE_INVALID) ||
594                 dbus_error_is_set (&error)) {
595                 fprintf(stderr, "Failed to parse resolver event.\n");
596                 goto fail;
597             }
598             
599             avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
600             r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, AVAHI_PROTO_UNSPEC, NULL, NULL, 0, r->userdata);
601             break;
602         }
603     }
604
605     return DBUS_HANDLER_RESULT_HANDLED;
606     
607 fail:
608     dbus_error_free (&error);
609     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
610 }
611
612 AvahiAddressResolver * avahi_address_resolver_new_a(
613     AvahiClient *client,
614     AvahiIfIndex interface,
615     AvahiProtocol protocol,
616     const AvahiAddress *a,
617     AvahiLookupFlags flags,
618     AvahiAddressResolverCallback callback,
619     void *userdata) {
620
621     char addr[AVAHI_ADDRESS_STR_MAX];
622
623     assert (a);
624
625     if (!avahi_address_snprint (addr, sizeof (addr), a)) {
626         avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS);
627         return NULL;
628     }
629
630     return avahi_address_resolver_new(
631         client, interface, protocol,
632         addr, flags,
633         callback, userdata);
634 }
635
636 AvahiAddressResolver * avahi_address_resolver_new(
637     AvahiClient *client,
638     AvahiIfIndex interface,
639     AvahiProtocol protocol,
640     const char *address,
641     AvahiLookupFlags flags, 
642     AvahiAddressResolverCallback callback,
643     void *userdata) {
644
645     DBusError error;
646     AvahiAddressResolver *r = NULL;
647     DBusMessage *message = NULL, *reply = NULL;
648     int32_t i_interface, i_protocol;
649     uint32_t u_flags;
650     char *path;
651     
652     assert(client);
653
654     dbus_error_init (&error);
655
656     if (client->state == AVAHI_CLIENT_DISCONNECTED) {
657         avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
658         goto fail;
659     }
660
661     if (!(r = avahi_new(AvahiAddressResolver, 1))) {
662         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
663         goto fail;
664     }
665
666     r->client = client;
667     r->callback = callback;
668     r->userdata = userdata;
669     r->path = NULL;
670     
671     AVAHI_LLIST_PREPEND(AvahiAddressResolver, address_resolvers, client->address_resolvers, r);
672
673     if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew"))) {
674         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
675         goto fail;
676     }
677
678     i_interface = (int32_t) interface;
679     i_protocol = (int32_t) protocol;
680     u_flags = (uint32_t) flags;
681
682     if (!(dbus_message_append_args(
683               message,
684               DBUS_TYPE_INT32, &i_interface,
685               DBUS_TYPE_INT32, &i_protocol,
686               DBUS_TYPE_STRING, &address,
687               DBUS_TYPE_UINT32, &u_flags,
688               DBUS_TYPE_INVALID))) {
689         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
690         goto fail;
691     }
692
693     if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) ||
694         dbus_error_is_set(&error)) {
695         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
696         goto fail;
697     }
698
699     if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
700         dbus_error_is_set(&error) ||
701         !path) {
702         avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
703         goto fail;
704     }
705     
706     if (!(r->path = avahi_strdup(path))) {
707
708         /* FIXME: We don't remove the object on the server side */
709
710         avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
711         goto fail;
712     }
713
714     dbus_message_unref(message);
715     dbus_message_unref(reply);
716
717     return r;
718     
719 fail:
720
721     if (dbus_error_is_set(&error)) {
722         avahi_client_set_dbus_error(client, &error);
723         dbus_error_free(&error);
724     }
725
726     if (r)
727         avahi_address_resolver_free(r);
728     
729     if (message)
730         dbus_message_unref(message);
731
732     if (reply)
733         dbus_message_unref(reply);
734
735     return NULL;
736
737 }
738
739 AvahiClient* avahi_address_resolver_get_client (AvahiAddressResolver *r) {
740     assert (r);
741
742     return r->client;
743 }
744
745 int avahi_address_resolver_free(AvahiAddressResolver *r) {
746     AvahiClient *client;
747     int ret = AVAHI_OK;
748
749     assert(r);
750     client = r->client;
751
752     if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED)
753         ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free");
754
755     AVAHI_LLIST_REMOVE(AvahiAddressResolver, address_resolvers, client->address_resolvers, r);
756
757     avahi_free(r->path);
758     avahi_free(r);
759
760     return ret;
761 }
762