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