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 void avahi_entry_group_set_state(AvahiEntryGroup *group, AvahiEntryGroupState state) { 40 assert(group); 41 42 if (group->state_valid && group->state == state) 43 return; 44 45 group->state = state; 46 group->state_valid = 1; 47 48 if (group->callback) 49 group->callback(group, state, group->userdata); 50 } 51 52 static int retrieve_state(AvahiEntryGroup *group) { 53 DBusMessage *message = NULL, *reply = NULL; 54 DBusError error; 55 int r = AVAHI_OK; 56 int32_t state; 57 AvahiClient *client; 58 59 dbus_error_init(&error); 60 61 assert(group); 62 client = group->client; 63 64 if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState"))) { 65 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 66 goto fail; 67 } 68 69 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 70 dbus_error_is_set (&error)) { 71 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 72 goto fail; 73 } 74 75 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID) || 76 dbus_error_is_set (&error)) { 77 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 78 goto fail; 79 } 80 81 dbus_message_unref(message); 82 dbus_message_unref(reply); 83 84 return state; 85 86 fail: 87 if (dbus_error_is_set(&error)) { 88 r = avahi_client_set_dbus_error(client, &error); 89 dbus_error_free(&error); 90 } 91 92 if (message) 93 dbus_message_unref(message); 94 95 if (reply) 96 dbus_message_unref(reply); 97 98 return r; 99 } 100 101 AvahiEntryGroup* avahi_entry_group_new (AvahiClient *client, AvahiEntryGroupCallback callback, void *userdata) { 102 AvahiEntryGroup *group = NULL; 103 DBusMessage *message = NULL, *reply = NULL; 104 DBusError error; 105 char *path; 106 int state; 107 108 assert(client); 109 110 dbus_error_init (&error); 111 112 if (!avahi_client_is_connected(client)) { 113 avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); 114 goto fail; 115 } 116 117 if (!(group = avahi_new(AvahiEntryGroup, 1))) { 118 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 119 goto fail; 120 } 121 122 group->client = client; 123 group->callback = callback; 124 group->userdata = userdata; 125 group->state_valid = 0; 126 group->path = NULL; 127 AVAHI_LLIST_PREPEND(AvahiEntryGroup, groups, client->groups, group); 128 129 if (!(message = dbus_message_new_method_call( 130 AVAHI_DBUS_NAME, 131 AVAHI_DBUS_PATH_SERVER, 132 AVAHI_DBUS_INTERFACE_SERVER, 133 "EntryGroupNew"))) { 134 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 135 goto fail; 136 } 137 138 if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) || 139 dbus_error_is_set (&error)) { 140 avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); 141 goto fail; 142 } 143 144 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || 145 dbus_error_is_set (&error)) { 146 avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); 147 goto fail; 148 } 149 150 if (!(group->path = avahi_strdup (path))) { 151 152 /* FIXME: We don't remove the object on the server side */ 153 154 avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 155 goto fail; 156 } 157 158 if ((state = retrieve_state(group)) < 0) { 159 avahi_client_set_errno(client, state); 160 goto fail; 161 } 162 163 avahi_entry_group_set_state(group, (AvahiEntryGroupState) state); 164 165 dbus_message_unref(message); 166 dbus_message_unref(reply); 167 168 return group; 169 170 fail: 171 if (dbus_error_is_set(&error)) { 172 avahi_client_set_dbus_error(client, &error); 173 dbus_error_free(&error); 174 } 175 176 if (group) 177 avahi_entry_group_free(group); 178 179 if (message) 180 dbus_message_unref(message); 181 182 if (reply) 183 dbus_message_unref(reply); 184 185 return NULL; 186 } 187 188 static int entry_group_simple_method_call(AvahiEntryGroup *group, const char *method) { 189 DBusMessage *message = NULL, *reply = NULL; 190 DBusError error; 191 int r = AVAHI_OK; 192 AvahiClient *client; 193 194 dbus_error_init(&error); 195 196 assert(group); 197 client = group->client; 198 199 if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, method))) { 200 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 201 goto fail; 202 } 203 204 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 205 dbus_error_is_set (&error)) { 206 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 207 goto fail; 208 } 209 210 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 211 dbus_error_is_set (&error)) { 212 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 213 goto fail; 214 } 215 216 dbus_message_unref(message); 217 dbus_message_unref(reply); 218 219 return AVAHI_OK; 220 221 fail: 222 if (dbus_error_is_set(&error)) { 223 r = avahi_client_set_dbus_error(client, &error); 224 dbus_error_free(&error); 225 } 226 227 if (message) 228 dbus_message_unref(message); 229 230 if (reply) 231 dbus_message_unref(reply); 232 233 return r; 234 } 235 236 int avahi_entry_group_free(AvahiEntryGroup *group) { 237 AvahiClient *client = group->client; 238 int r = AVAHI_OK; 239 240 assert(group); 241 242 if (group->path && avahi_client_is_connected(client)) 243 r = entry_group_simple_method_call(group, "Free"); 244 245 AVAHI_LLIST_REMOVE(AvahiEntryGroup, groups, client->groups, group); 246 247 avahi_free(group->path); 248 avahi_free(group); 249 250 return r; 251 } 252 253 int avahi_entry_group_commit(AvahiEntryGroup *group) { 254 int ret; 255 assert(group); 256 257 if (!group->path || !avahi_client_is_connected(group->client)) 258 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 259 260 if ((ret = entry_group_simple_method_call(group, "Commit")) < 0) 261 return ret; 262 263 group->state_valid = 0; 264 return ret; 265 } 266 267 int avahi_entry_group_reset(AvahiEntryGroup *group) { 268 int ret; 269 assert(group); 270 271 if (!group->path || !avahi_client_is_connected(group->client)) 272 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 273 274 if ((ret = entry_group_simple_method_call(group, "Reset")) < 0) 275 return ret; 276 277 group->state_valid = 0; 278 return ret; 279 } 280 281 int avahi_entry_group_get_state (AvahiEntryGroup *group) { 282 assert (group); 283 284 if (group->state_valid) 285 return group->state; 286 287 return retrieve_state(group); 288 } 289 290 AvahiClient* avahi_entry_group_get_client (AvahiEntryGroup *group) { 291 assert(group); 292 293 return group->client; 294 } 295 296 int avahi_entry_group_is_empty (AvahiEntryGroup *group) { 297 DBusMessage *message = NULL, *reply = NULL; 298 DBusError error; 299 int r = AVAHI_OK; 300 int b; 301 AvahiClient *client; 302 303 assert(group); 304 client = group->client; 305 306 if (!group->path || !avahi_client_is_connected(group->client)) 307 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 308 309 dbus_error_init(&error); 310 311 if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "IsEmpty"))) { 312 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 313 goto fail; 314 } 315 316 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 317 dbus_error_is_set (&error)) { 318 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 319 goto fail; 320 } 321 322 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID) || 323 dbus_error_is_set (&error)) { 324 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 325 goto fail; 326 } 327 328 dbus_message_unref(message); 329 dbus_message_unref(reply); 330 331 return !!b; 332 333 fail: 334 if (dbus_error_is_set(&error)) { 335 r = avahi_client_set_dbus_error(client, &error); 336 dbus_error_free(&error); 337 } 338 339 if (message) 340 dbus_message_unref(message); 341 342 if (reply) 343 dbus_message_unref(reply); 344 345 return r; 346 } 347 348 static int append_rdata(DBusMessage *message, const void *rdata, size_t size) { 349 DBusMessageIter iter, sub; 350 351 assert(message); 352 353 dbus_message_iter_init_append(message, &iter); 354 355 if (!(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &sub)) || 356 !(dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &rdata, size)) || 357 !(dbus_message_iter_close_container(&iter, &sub))) 358 return -1; 359 360 return 0; 361 } 362 363 static int append_string_list(DBusMessage *message, AvahiStringList *txt) { 364 DBusMessageIter iter, sub; 365 int r = -1; 366 AvahiStringList *p; 367 368 assert(message); 369 370 dbus_message_iter_init_append(message, &iter); 371 372 /* Reverse the string list, so that we can pass it in-order to the server */ 373 txt = avahi_string_list_reverse(txt); 374 375 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub)) 376 goto fail; 377 378 /* Assemble the AvahiStringList into an Array of Array of Bytes to send over dbus */ 379 for (p = txt; p != NULL; p = p->next) { 380 DBusMessageIter sub2; 381 const uint8_t *data = p->text; 382 383 if (!(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2)) || 384 !(dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size)) || 385 !(dbus_message_iter_close_container(&sub, &sub2))) 386 goto fail; 387 } 388 389 if (!dbus_message_iter_close_container(&iter, &sub)) 390 goto fail; 391 392 r = 0; 393 394 fail: 395 396 /* Reverse the string list to the original state */ 397 txt = avahi_string_list_reverse(txt); 398 399 return r; 400 } 401 402 int avahi_entry_group_add_service_strlst( 403 AvahiEntryGroup *group, 404 AvahiIfIndex interface, 405 AvahiProtocol protocol, 406 AvahiPublishFlags flags, 407 const char *name, 408 const char *type, 409 const char *domain, 410 const char *host, 411 uint16_t port, 412 AvahiStringList *txt) { 413 414 DBusMessage *message = NULL, *reply = NULL; 415 int r = AVAHI_OK; 416 DBusError error; 417 AvahiClient *client; 418 int32_t i_interface, i_protocol; 419 uint32_t u_flags; 420 421 assert(group); 422 assert(name); 423 assert(type); 424 425 client = group->client; 426 427 if (!group->path || !avahi_client_is_connected(group->client)) 428 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 429 430 if (!domain) 431 domain = ""; 432 433 if (!host) 434 host = ""; 435 436 dbus_error_init(&error); 437 438 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService"))) { 439 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 440 goto fail; 441 } 442 443 i_interface = (int32_t) interface; 444 i_protocol = (int32_t) protocol; 445 u_flags = (uint32_t) flags; 446 447 if (!dbus_message_append_args( 448 message, 449 DBUS_TYPE_INT32, &i_interface, 450 DBUS_TYPE_INT32, &i_protocol, 451 DBUS_TYPE_UINT32, &u_flags, 452 DBUS_TYPE_STRING, &name, 453 DBUS_TYPE_STRING, &type, 454 DBUS_TYPE_STRING, &domain, 455 DBUS_TYPE_STRING, &host, 456 DBUS_TYPE_UINT16, &port, 457 DBUS_TYPE_INVALID) || 458 append_string_list(message, txt) < 0) { 459 r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); 460 goto fail; 461 } 462 463 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 464 dbus_error_is_set (&error)) { 465 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 466 goto fail; 467 } 468 469 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 470 dbus_error_is_set (&error)) { 471 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 472 goto fail; 473 } 474 475 dbus_message_unref(message); 476 dbus_message_unref(reply); 477 478 return AVAHI_OK; 479 480 fail: 481 482 if (dbus_error_is_set(&error)) { 483 r = avahi_client_set_dbus_error(client, &error); 484 dbus_error_free(&error); 485 } 486 487 if (message) 488 dbus_message_unref(message); 489 490 if (reply) 491 dbus_message_unref(reply); 492 493 return r; 494 } 495 496 int avahi_entry_group_add_service( 497 AvahiEntryGroup *group, 498 AvahiIfIndex interface, 499 AvahiProtocol protocol, 500 AvahiPublishFlags flags, 501 const char *name, 502 const char *type, 503 const char *domain, 504 const char *host, 505 uint16_t port, 506 ...) { 507 508 va_list va; 509 int r; 510 AvahiStringList *txt; 511 512 assert(group); 513 514 va_start(va, port); 515 txt = avahi_string_list_new_va(va); 516 r = avahi_entry_group_add_service_strlst(group, interface, protocol, flags, name, type, domain, host, port, txt); 517 avahi_string_list_free(txt); 518 va_end(va); 519 return r; 520 } 521 522 int avahi_entry_group_add_service_subtype( 523 AvahiEntryGroup *group, 524 AvahiIfIndex interface, 525 AvahiProtocol protocol, 526 AvahiPublishFlags flags, 527 const char *name, 528 const char *type, 529 const char *domain, 530 const char *subtype) { 531 532 DBusMessage *message = NULL, *reply = NULL; 533 int r = AVAHI_OK; 534 DBusError error; 535 AvahiClient *client; 536 int32_t i_interface, i_protocol; 537 uint32_t u_flags; 538 539 assert(group); 540 assert(name); 541 assert(type); 542 assert(subtype); 543 544 client = group->client; 545 546 if (!group->path || !avahi_client_is_connected(group->client)) 547 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 548 549 if (!domain) 550 domain = ""; 551 552 dbus_error_init(&error); 553 554 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddServiceSubtype"))) { 555 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 556 goto fail; 557 } 558 559 i_interface = (int32_t) interface; 560 i_protocol = (int32_t) protocol; 561 u_flags = (uint32_t) flags; 562 563 if (!dbus_message_append_args( 564 message, 565 DBUS_TYPE_INT32, &i_interface, 566 DBUS_TYPE_INT32, &i_protocol, 567 DBUS_TYPE_UINT32, &u_flags, 568 DBUS_TYPE_STRING, &name, 569 DBUS_TYPE_STRING, &type, 570 DBUS_TYPE_STRING, &domain, 571 DBUS_TYPE_STRING, &subtype, 572 DBUS_TYPE_INVALID)) { 573 r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); 574 goto fail; 575 } 576 577 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 578 dbus_error_is_set (&error)) { 579 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 580 goto fail; 581 } 582 583 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 584 dbus_error_is_set (&error)) { 585 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 586 goto fail; 587 } 588 589 dbus_message_unref(message); 590 dbus_message_unref(reply); 591 592 return AVAHI_OK; 593 594 fail: 595 596 if (dbus_error_is_set(&error)) { 597 r = avahi_client_set_dbus_error(client, &error); 598 dbus_error_free(&error); 599 } 600 601 if (message) 602 dbus_message_unref(message); 603 604 if (reply) 605 dbus_message_unref(reply); 606 607 return r; 608 609 } 610 611 int avahi_entry_group_update_service_txt( 612 AvahiEntryGroup *group, 613 AvahiIfIndex interface, 614 AvahiProtocol protocol, 615 AvahiPublishFlags flags, 616 const char *name, 617 const char *type, 618 const char *domain, 619 ...) { 620 621 va_list va; 622 int r; 623 AvahiStringList *txt; 624 625 va_start(va, domain); 626 txt = avahi_string_list_new_va(va); 627 r = avahi_entry_group_update_service_txt_strlst(group, interface, protocol, flags, name, type, domain, txt); 628 avahi_string_list_free(txt); 629 va_end(va); 630 return r; 631 } 632 633 int avahi_entry_group_update_service_txt_strlst( 634 AvahiEntryGroup *group, 635 AvahiIfIndex interface, 636 AvahiProtocol protocol, 637 AvahiPublishFlags flags, 638 const char *name, 639 const char *type, 640 const char *domain, 641 AvahiStringList *txt) { 642 643 DBusMessage *message = NULL, *reply = NULL; 644 int r = AVAHI_OK; 645 DBusError error; 646 AvahiClient *client; 647 int32_t i_interface, i_protocol; 648 uint32_t u_flags; 649 650 assert(group); 651 assert(name); 652 assert(type); 653 654 client = group->client; 655 656 if (!group->path || !avahi_client_is_connected(group->client)) 657 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 658 659 if (!domain) 660 domain = ""; 661 662 dbus_error_init(&error); 663 664 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "UpdateServiceTxt"))) { 665 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 666 goto fail; 667 } 668 669 i_interface = (int32_t) interface; 670 i_protocol = (int32_t) protocol; 671 u_flags = (uint32_t) flags; 672 673 if (!dbus_message_append_args( 674 message, 675 DBUS_TYPE_INT32, &i_interface, 676 DBUS_TYPE_INT32, &i_protocol, 677 DBUS_TYPE_UINT32, &u_flags, 678 DBUS_TYPE_STRING, &name, 679 DBUS_TYPE_STRING, &type, 680 DBUS_TYPE_STRING, &domain, 681 DBUS_TYPE_INVALID) || 682 append_string_list(message, txt) < 0) { 683 r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); 684 goto fail; 685 } 686 687 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 688 dbus_error_is_set (&error)) { 689 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 690 goto fail; 691 } 692 693 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 694 dbus_error_is_set (&error)) { 695 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 696 goto fail; 697 } 698 699 dbus_message_unref(message); 700 dbus_message_unref(reply); 701 702 return AVAHI_OK; 703 704 fail: 705 706 if (dbus_error_is_set(&error)) { 707 r = avahi_client_set_dbus_error(client, &error); 708 dbus_error_free(&error); 709 } 710 711 if (message) 712 dbus_message_unref(message); 713 714 if (reply) 715 dbus_message_unref(reply); 716 717 return r; 718 } 719 720 /** Add a host/address pair */ 721 int avahi_entry_group_add_address( 722 AvahiEntryGroup *group, 723 AvahiIfIndex interface, 724 AvahiProtocol protocol, 725 AvahiPublishFlags flags, 726 const char *name, 727 const AvahiAddress *a) { 728 729 DBusMessage *message = NULL, *reply = NULL; 730 int r = AVAHI_OK; 731 DBusError error; 732 AvahiClient *client; 733 int32_t i_interface, i_protocol; 734 uint32_t u_flags; 735 char s_address[AVAHI_ADDRESS_STR_MAX]; 736 char *p_address = s_address; 737 738 assert(name); 739 740 client = group->client; 741 742 if (!group->path || !avahi_client_is_connected(group->client)) 743 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 744 745 dbus_error_init(&error); 746 747 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddAddress"))) { 748 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 749 goto fail; 750 } 751 752 i_interface = (int32_t) interface; 753 i_protocol = (int32_t) protocol; 754 u_flags = (uint32_t) flags; 755 756 if (!avahi_address_snprint (s_address, sizeof (s_address), a)) 757 { 758 r = avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS); 759 goto fail; 760 } 761 762 if (!dbus_message_append_args( 763 message, 764 DBUS_TYPE_INT32, &i_interface, 765 DBUS_TYPE_INT32, &i_protocol, 766 DBUS_TYPE_UINT32, &u_flags, 767 DBUS_TYPE_STRING, &name, 768 DBUS_TYPE_STRING, &p_address, 769 DBUS_TYPE_INVALID)) { 770 r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); 771 goto fail; 772 } 773 774 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 775 dbus_error_is_set (&error)) { 776 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 777 goto fail; 778 } 779 780 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 781 dbus_error_is_set (&error)) { 782 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 783 goto fail; 784 } 785 786 dbus_message_unref(message); 787 dbus_message_unref(reply); 788 789 return AVAHI_OK; 790 791 fail: 792 793 if (dbus_error_is_set(&error)) { 794 r = avahi_client_set_dbus_error(client, &error); 795 dbus_error_free(&error); 796 } 797 798 if (message) 799 dbus_message_unref(message); 800 801 if (reply) 802 dbus_message_unref(reply); 803 804 return r; 805 } 806 807 /** Add an arbitrary record */ 808 int avahi_entry_group_add_record( 809 AvahiEntryGroup *group, 810 AvahiIfIndex interface, 811 AvahiProtocol protocol, 812 AvahiPublishFlags flags, 813 const char *name, 814 uint16_t clazz, 815 uint16_t type, 816 uint32_t ttl, 817 const void *rdata, 818 size_t size) { 819 820 DBusMessage *message = NULL, *reply = NULL; 821 int r = AVAHI_OK; 822 DBusError error; 823 AvahiClient *client; 824 int32_t i_interface, i_protocol; 825 uint32_t u_flags; 826 827 assert(name); 828 829 client = group->client; 830 831 if (!group->path || !avahi_client_is_connected(group->client)) 832 return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); 833 834 dbus_error_init(&error); 835 836 if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddRecord"))) { 837 r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); 838 goto fail; 839 } 840 841 i_interface = (int32_t) interface; 842 i_protocol = (int32_t) protocol; 843 u_flags = (uint32_t) flags; 844 845 if (!dbus_message_append_args( 846 message, 847 DBUS_TYPE_INT32, &i_interface, 848 DBUS_TYPE_INT32, &i_protocol, 849 DBUS_TYPE_UINT32, &u_flags, 850 DBUS_TYPE_STRING, &name, 851 DBUS_TYPE_UINT16, &clazz, 852 DBUS_TYPE_UINT16, &type, 853 DBUS_TYPE_UINT32, &ttl, 854 DBUS_TYPE_INVALID) || append_rdata(message, rdata, size) < 0) { 855 r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); 856 goto fail; 857 } 858 859 if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || 860 dbus_error_is_set (&error)) { 861 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 862 goto fail; 863 } 864 865 if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || 866 dbus_error_is_set (&error)) { 867 r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); 868 goto fail; 869 } 870 871 dbus_message_unref(message); 872 dbus_message_unref(reply); 873 874 return AVAHI_OK; 875 876 fail: 877 878 if (dbus_error_is_set(&error)) { 879 r = avahi_client_set_dbus_error(client, &error); 880 dbus_error_free(&error); 881 } 882 883 if (message) 884 dbus_message_unref(message); 885 886 if (reply) 887 dbus_message_unref(reply); 888 889 return r; 890 } 891