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