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