1 /* -*- mode: C; c-file-style: "gnu" -*- */ 2 /* driver.c Bus client (driver) 3 * 4 * Copyright (C) 2003 CodeFactory AB 5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25 #include "activation.h" 26 #include "connection.h" 27 #include "driver.h" 28 #include "dispatch.h" 29 #include "services.h" 30 #include "selinux.h" 31 #include "signals.h" 32 #include "utils.h" 33 #include <dbus/dbus-string.h> 34 #include <dbus/dbus-internals.h> 35 #include <dbus/dbus-marshal-recursive.h> 36 #include <string.h> 37 38 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection, 39 DBusMessage *hello_message, 40 BusTransaction *transaction, 41 DBusError *error); 42 43 dbus_bool_t 44 bus_driver_send_service_owner_changed (const char *service_name, 45 const char *old_owner, 46 const char *new_owner, 47 BusTransaction *transaction, 48 DBusError *error) 49 { 50 DBusMessage *message; 51 dbus_bool_t retval; 52 const char *null_service; 53 54 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 55 56 null_service = ""; 57 _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n", 58 service_name, 59 old_owner ? old_owner : null_service, 60 new_owner ? new_owner : null_service); 61 62 message = dbus_message_new_signal (DBUS_PATH_DBUS, 63 DBUS_INTERFACE_DBUS, 64 "NameOwnerChanged"); 65 66 if (message == NULL) 67 { 68 BUS_SET_OOM (error); 69 return FALSE; 70 } 71 72 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) 73 goto oom; 74 75 if (!dbus_message_append_args (message, 76 DBUS_TYPE_STRING, &service_name, 77 DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service, 78 DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service, 79 DBUS_TYPE_INVALID)) 80 goto oom; 81 82 _dbus_assert (dbus_message_has_signature (message, "sss")); 83 84 retval = bus_dispatch_matches (transaction, NULL, NULL, message, error); 85 dbus_message_unref (message); 86 87 return retval; 88 89 oom: 90 dbus_message_unref (message); 91 BUS_SET_OOM (error); 92 return FALSE; 93 } 94 95 dbus_bool_t 96 bus_driver_send_service_lost (DBusConnection *connection, 97 const char *service_name, 98 BusTransaction *transaction, 99 DBusError *error) 100 { 101 DBusMessage *message; 102 103 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 104 105 message = dbus_message_new_signal (DBUS_PATH_DBUS, 106 DBUS_INTERFACE_DBUS, 107 "NameLost"); 108 109 if (message == NULL) 110 { 111 BUS_SET_OOM (error); 112 return FALSE; 113 } 114 115 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) || 116 !dbus_message_append_args (message, 117 DBUS_TYPE_STRING, &service_name, 118 DBUS_TYPE_INVALID)) 119 { 120 dbus_message_unref (message); 121 BUS_SET_OOM (error); 122 return FALSE; 123 } 124 125 if (!bus_transaction_send_from_driver (transaction, connection, message)) 126 { 127 dbus_message_unref (message); 128 BUS_SET_OOM (error); 129 return FALSE; 130 } 131 else 132 { 133 dbus_message_unref (message); 134 return TRUE; 135 } 136 } 137 138 dbus_bool_t 139 bus_driver_send_service_acquired (DBusConnection *connection, 140 const char *service_name, 141 BusTransaction *transaction, 142 DBusError *error) 143 { 144 DBusMessage *message; 145 146 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 147 148 message = dbus_message_new_signal (DBUS_PATH_DBUS, 149 DBUS_INTERFACE_DBUS, 150 "NameAcquired"); 151 152 if (message == NULL) 153 { 154 BUS_SET_OOM (error); 155 return FALSE; 156 } 157 158 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) || 159 !dbus_message_append_args (message, 160 DBUS_TYPE_STRING, &service_name, 161 DBUS_TYPE_INVALID)) 162 { 163 dbus_message_unref (message); 164 BUS_SET_OOM (error); 165 return FALSE; 166 } 167 168 if (!bus_transaction_send_from_driver (transaction, connection, message)) 169 { 170 dbus_message_unref (message); 171 BUS_SET_OOM (error); 172 return FALSE; 173 } 174 else 175 { 176 dbus_message_unref (message); 177 return TRUE; 178 } 179 } 180 181 static dbus_bool_t 182 create_unique_client_name (BusRegistry *registry, 183 DBusString *str) 184 { 185 /* We never want to use the same unique client name twice, because 186 * we want to guarantee that if you send a message to a given unique 187 * name, you always get the same application. So we use two numbers 188 * for INT_MAX * INT_MAX combinations, should be pretty safe against 189 * wraparound. 190 */ 191 /* FIXME these should be in BusRegistry rather than static vars */ 192 static int next_major_number = 0; 193 static int next_minor_number = 0; 194 int len; 195 196 len = _dbus_string_get_length (str); 197 198 while (TRUE) 199 { 200 /* start out with 1-0, go to 1-1, 1-2, 1-3, 201 * up to 1-MAXINT, then 2-0, 2-1, etc. 202 */ 203 if (next_minor_number <= 0) 204 { 205 next_major_number += 1; 206 next_minor_number = 0; 207 if (next_major_number <= 0) 208 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added"); 209 } 210 211 _dbus_assert (next_major_number > 0); 212 _dbus_assert (next_minor_number >= 0); 213 214 /* appname:MAJOR-MINOR */ 215 216 if (!_dbus_string_append (str, ":")) 217 return FALSE; 218 219 if (!_dbus_string_append_int (str, next_major_number)) 220 return FALSE; 221 222 if (!_dbus_string_append (str, ".")) 223 return FALSE; 224 225 if (!_dbus_string_append_int (str, next_minor_number)) 226 return FALSE; 227 228 next_minor_number += 1; 229 230 /* Check if a client with the name exists */ 231 if (bus_registry_lookup (registry, str) == NULL) 232 break; 233 234 /* drop the number again, try the next one. */ 235 _dbus_string_set_length (str, len); 236 } 237 238 return TRUE; 239 } 240 241 static dbus_bool_t 242 bus_driver_handle_hello (DBusConnection *connection, 243 BusTransaction *transaction, 244 DBusMessage *message, 245 DBusError *error) 246 { 247 DBusString unique_name; 248 BusService *service; 249 dbus_bool_t retval; 250 BusRegistry *registry; 251 BusConnections *connections; 252 253 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 254 255 if (bus_connection_is_active (connection)) 256 { 257 /* We already handled an Hello message for this connection. */ 258 dbus_set_error (error, DBUS_ERROR_FAILED, 259 "Already handled an Hello message"); 260 return FALSE; 261 } 262 263 /* Note that when these limits are exceeded we don't disconnect the 264 * connection; we just sort of leave it hanging there until it times 265 * out or disconnects itself or is dropped due to the max number of 266 * incomplete connections. It's even OK if the connection wants to 267 * retry the hello message, we support that. 268 */ 269 connections = bus_connection_get_connections (connection); 270 if (!bus_connections_check_limits (connections, connection, 271 error)) 272 { 273 _DBUS_ASSERT_ERROR_IS_SET (error); 274 return FALSE; 275 } 276 277 if (!_dbus_string_init (&unique_name)) 278 { 279 BUS_SET_OOM (error); 280 return FALSE; 281 } 282 283 retval = FALSE; 284 285 registry = bus_connection_get_registry (connection); 286 287 if (!create_unique_client_name (registry, &unique_name)) 288 { 289 BUS_SET_OOM (error); 290 goto out_0; 291 } 292 293 if (!bus_connection_complete (connection, &unique_name, error)) 294 { 295 _DBUS_ASSERT_ERROR_IS_SET (error); 296 goto out_0; 297 } 298 299 if (!dbus_message_set_sender (message, 300 bus_connection_get_name (connection))) 301 { 302 BUS_SET_OOM (error); 303 goto out_0; 304 } 305 306 if (!bus_driver_send_welcome_message (connection, message, transaction, error)) 307 goto out_0; 308 309 /* Create the service */ 310 service = bus_registry_ensure (registry, 311 &unique_name, connection, 0, transaction, error); 312 if (service == NULL) 313 goto out_0; 314 315 _dbus_assert (bus_connection_is_active (connection)); 316 retval = TRUE; 317 318 out_0: 319 _dbus_string_free (&unique_name); 320 return retval; 321 } 322 323 static dbus_bool_t 324 bus_driver_send_welcome_message (DBusConnection *connection, 325 DBusMessage *hello_message, 326 BusTransaction *transaction, 327 DBusError *error) 328 { 329 DBusMessage *welcome; 330 const char *name; 331 332 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 333 334 name = bus_connection_get_name (connection); 335 _dbus_assert (name != NULL); 336 337 welcome = dbus_message_new_method_return (hello_message); 338 if (welcome == NULL) 339 { 340 BUS_SET_OOM (error); 341 return FALSE; 342 } 343 344 if (!dbus_message_append_args (welcome, 345 DBUS_TYPE_STRING, &name, 346 DBUS_TYPE_INVALID)) 347 { 348 dbus_message_unref (welcome); 349 BUS_SET_OOM (error); 350 return FALSE; 351 } 352 353 _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING)); 354 355 if (!bus_transaction_send_from_driver (transaction, connection, welcome)) 356 { 357 dbus_message_unref (welcome); 358 BUS_SET_OOM (error); 359 return FALSE; 360 } 361 else 362 { 363 dbus_message_unref (welcome); 364 return TRUE; 365 } 366 } 367 368 static dbus_bool_t 369 bus_driver_handle_list_services (DBusConnection *connection, 370 BusTransaction *transaction, 371 DBusMessage *message, 372 DBusError *error) 373 { 374 DBusMessage *reply; 375 int len; 376 char **services; 377 BusRegistry *registry; 378 int i; 379 DBusMessageIter iter; 380 DBusMessageIter sub; 381 382 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 383 384 registry = bus_connection_get_registry (connection); 385 386 reply = dbus_message_new_method_return (message); 387 if (reply == NULL) 388 { 389 BUS_SET_OOM (error); 390 return FALSE; 391 } 392 393 if (!bus_registry_list_services (registry, &services, &len)) 394 { 395 dbus_message_unref (reply); 396 BUS_SET_OOM (error); 397 return FALSE; 398 } 399 400 dbus_message_iter_init_append (reply, &iter); 401 402 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 403 DBUS_TYPE_STRING_AS_STRING, 404 &sub)) 405 { 406 dbus_free_string_array (services); 407 dbus_message_unref (reply); 408 BUS_SET_OOM (error); 409 return FALSE; 410 } 411 412 { 413 /* Include the bus driver in the list */ 414 const char *v_STRING = DBUS_SERVICE_DBUS; 415 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 416 &v_STRING)) 417 { 418 dbus_free_string_array (services); 419 dbus_message_unref (reply); 420 BUS_SET_OOM (error); 421 return FALSE; 422 } 423 } 424 425 i = 0; 426 while (i < len) 427 { 428 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 429 &services[i])) 430 { 431 dbus_free_string_array (services); 432 dbus_message_unref (reply); 433 BUS_SET_OOM (error); 434 return FALSE; 435 } 436 ++i; 437 } 438 439 dbus_free_string_array (services); 440 441 if (!dbus_message_iter_close_container (&iter, &sub)) 442 { 443 dbus_message_unref (reply); 444 BUS_SET_OOM (error); 445 return FALSE; 446 } 447 448 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 449 { 450 dbus_message_unref (reply); 451 BUS_SET_OOM (error); 452 return FALSE; 453 } 454 else 455 { 456 dbus_message_unref (reply); 457 return TRUE; 458 } 459 } 460 461 static dbus_bool_t 462 bus_driver_handle_list_activatable_services (DBusConnection *connection, 463 BusTransaction *transaction, 464 DBusMessage *message, 465 DBusError *error) 466 { 467 DBusMessage *reply; 468 int len; 469 char **services; 470 BusActivation *activation; 471 int i; 472 DBusMessageIter iter; 473 DBusMessageIter sub; 474 475 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 476 477 activation = bus_connection_get_activation (connection); 478 479 reply = dbus_message_new_method_return (message); 480 if (reply == NULL) 481 { 482 BUS_SET_OOM (error); 483 return FALSE; 484 } 485 486 if (!bus_activation_list_services (activation, &services, &len)) 487 { 488 dbus_message_unref (reply); 489 BUS_SET_OOM (error); 490 return FALSE; 491 } 492 493 dbus_message_iter_init_append (reply, &iter); 494 495 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 496 DBUS_TYPE_STRING_AS_STRING, 497 &sub)) 498 { 499 dbus_free_string_array (services); 500 dbus_message_unref (reply); 501 BUS_SET_OOM (error); 502 return FALSE; 503 } 504 505 { 506 /* Include the bus driver in the list */ 507 const char *v_STRING = DBUS_SERVICE_DBUS; 508 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 509 &v_STRING)) 510 { 511 dbus_free_string_array (services); 512 dbus_message_unref (reply); 513 BUS_SET_OOM (error); 514 return FALSE; 515 } 516 } 517 518 i = 0; 519 while (i < len) 520 { 521 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 522 &services[i])) 523 { 524 dbus_free_string_array (services); 525 dbus_message_unref (reply); 526 BUS_SET_OOM (error); 527 return FALSE; 528 } 529 ++i; 530 } 531 532 dbus_free_string_array (services); 533 534 if (!dbus_message_iter_close_container (&iter, &sub)) 535 { 536 dbus_message_unref (reply); 537 BUS_SET_OOM (error); 538 return FALSE; 539 } 540 541 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 542 { 543 dbus_message_unref (reply); 544 BUS_SET_OOM (error); 545 return FALSE; 546 } 547 else 548 { 549 dbus_message_unref (reply); 550 return TRUE; 551 } 552 } 553 554 static dbus_bool_t 555 bus_driver_handle_acquire_service (DBusConnection *connection, 556 BusTransaction *transaction, 557 DBusMessage *message, 558 DBusError *error) 559 { 560 DBusMessage *reply; 561 DBusString service_name; 562 const char *name; 563 dbus_uint32_t service_reply; 564 dbus_uint32_t flags; 565 dbus_bool_t retval; 566 BusRegistry *registry; 567 568 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 569 570 registry = bus_connection_get_registry (connection); 571 572 if (!dbus_message_get_args (message, error, 573 DBUS_TYPE_STRING, &name, 574 DBUS_TYPE_UINT32, &flags, 575 DBUS_TYPE_INVALID)) 576 return FALSE; 577 578 _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags); 579 580 retval = FALSE; 581 reply = NULL; 582 583 _dbus_string_init_const (&service_name, name); 584 585 if (!bus_registry_acquire_service (registry, connection, 586 &service_name, flags, 587 &service_reply, transaction, 588 error)) 589 goto out; 590 591 reply = dbus_message_new_method_return (message); 592 if (reply == NULL) 593 { 594 BUS_SET_OOM (error); 595 goto out; 596 } 597 598 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID)) 599 { 600 BUS_SET_OOM (error); 601 goto out; 602 } 603 604 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 605 { 606 BUS_SET_OOM (error); 607 goto out; 608 } 609 610 retval = TRUE; 611 612 out: 613 if (reply) 614 dbus_message_unref (reply); 615 return retval; 616 } 617 618 static dbus_bool_t 619 bus_driver_handle_release_service (DBusConnection *connection, 620 BusTransaction *transaction, 621 DBusMessage *message, 622 DBusError *error) 623 { 624 DBusMessage *reply; 625 DBusString service_name; 626 const char *name; 627 dbus_uint32_t service_reply; 628 dbus_bool_t retval; 629 BusRegistry *registry; 630 631 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 632 633 registry = bus_connection_get_registry (connection); 634 635 if (!dbus_message_get_args (message, error, 636 DBUS_TYPE_STRING, &name, 637 DBUS_TYPE_INVALID)) 638 return FALSE; 639 640 _dbus_verbose ("Trying to release name %s\n", name); 641 642 retval = FALSE; 643 reply = NULL; 644 645 _dbus_string_init_const (&service_name, name); 646 647 if (!bus_registry_release_service (registry, connection, 648 &service_name, &service_reply, 649 transaction, error)) 650 goto out; 651 652 reply = dbus_message_new_method_return (message); 653 if (reply == NULL) 654 { 655 BUS_SET_OOM (error); 656 goto out; 657 } 658 659 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID)) 660 { 661 BUS_SET_OOM (error); 662 goto out; 663 } 664 665 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 666 { 667 BUS_SET_OOM (error); 668 goto out; 669 } 670 671 retval = TRUE; 672 673 out: 674 if (reply) 675 dbus_message_unref (reply); 676 return retval; 677 } 678 679 static dbus_bool_t 680 bus_driver_handle_service_exists (DBusConnection *connection, 681 BusTransaction *transaction, 682 DBusMessage *message, 683 DBusError *error) 684 { 685 DBusMessage *reply; 686 DBusString service_name; 687 BusService *service; 688 dbus_bool_t service_exists; 689 const char *name; 690 dbus_bool_t retval; 691 BusRegistry *registry; 692 693 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 694 695 registry = bus_connection_get_registry (connection); 696 697 if (!dbus_message_get_args (message, error, 698 DBUS_TYPE_STRING, &name, 699 DBUS_TYPE_INVALID)) 700 return FALSE; 701 702 retval = FALSE; 703 704 if (strcmp (name, DBUS_SERVICE_DBUS) == 0) 705 { 706 service_exists = TRUE; 707 } 708 else 709 { 710 _dbus_string_init_const (&service_name, name); 711 service = bus_registry_lookup (registry, &service_name); 712 service_exists = service != NULL; 713 } 714 715 reply = dbus_message_new_method_return (message); 716 if (reply == NULL) 717 { 718 BUS_SET_OOM (error); 719 goto out; 720 } 721 722 if (!dbus_message_append_args (reply, 723 DBUS_TYPE_BOOLEAN, &service_exists, 724 0)) 725 { 726 BUS_SET_OOM (error); 727 goto out; 728 } 729 730 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 731 { 732 BUS_SET_OOM (error); 733 goto out; 734 } 735 736 retval = TRUE; 737 738 out: 739 if (reply) 740 dbus_message_unref (reply); 741 742 return retval; 743 } 744 745 static dbus_bool_t 746 bus_driver_handle_activate_service (DBusConnection *connection, 747 BusTransaction *transaction, 748 DBusMessage *message, 749 DBusError *error) 750 { 751 dbus_uint32_t flags; 752 const char *name; 753 dbus_bool_t retval; 754 BusActivation *activation; 755 756 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 757 758 activation = bus_connection_get_activation (connection); 759 760 if (!dbus_message_get_args (message, error, 761 DBUS_TYPE_STRING, &name, 762 DBUS_TYPE_UINT32, &flags, 763 DBUS_TYPE_INVALID)) 764 { 765 _DBUS_ASSERT_ERROR_IS_SET (error); 766 _dbus_verbose ("No memory to get arguments to StartServiceByName\n"); 767 return FALSE; 768 } 769 770 retval = FALSE; 771 772 if (!bus_activation_activate_service (activation, connection, transaction, FALSE, 773 message, name, error)) 774 { 775 _DBUS_ASSERT_ERROR_IS_SET (error); 776 _dbus_verbose ("bus_activation_activate_service() failed\n"); 777 goto out; 778 } 779 780 retval = TRUE; 781 782 out: 783 return retval; 784 } 785 786 static dbus_bool_t 787 send_ack_reply (DBusConnection *connection, 788 BusTransaction *transaction, 789 DBusMessage *message, 790 DBusError *error) 791 { 792 DBusMessage *reply; 793 794 reply = dbus_message_new_method_return (message); 795 if (reply == NULL) 796 { 797 BUS_SET_OOM (error); 798 return FALSE; 799 } 800 801 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 802 { 803 BUS_SET_OOM (error); 804 dbus_message_unref (reply); 805 return FALSE; 806 } 807 808 dbus_message_unref (reply); 809 810 return TRUE; 811 } 812 813 static dbus_bool_t 814 bus_driver_handle_add_match (DBusConnection *connection, 815 BusTransaction *transaction, 816 DBusMessage *message, 817 DBusError *error) 818 { 819 BusMatchRule *rule; 820 const char *text; 821 DBusString str; 822 BusMatchmaker *matchmaker; 823 824 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 825 826 text = NULL; 827 rule = NULL; 828 829 if (bus_connection_get_n_match_rules (connection) >= 830 bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction))) 831 { 832 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, 833 "Connection \"%s\" is not allowed to add more match rules " 834 "(increase limits in configuration file if required)", 835 bus_connection_is_active (connection) ? 836 bus_connection_get_name (connection) : 837 "(inactive)"); 838 goto failed; 839 } 840 841 if (!dbus_message_get_args (message, error, 842 DBUS_TYPE_STRING, &text, 843 DBUS_TYPE_INVALID)) 844 { 845 _dbus_verbose ("No memory to get arguments to AddMatch\n"); 846 goto failed; 847 } 848 849 _dbus_string_init_const (&str, text); 850 851 rule = bus_match_rule_parse (connection, &str, error); 852 if (rule == NULL) 853 goto failed; 854 855 matchmaker = bus_connection_get_matchmaker (connection); 856 857 if (!bus_matchmaker_add_rule (matchmaker, rule)) 858 { 859 BUS_SET_OOM (error); 860 goto failed; 861 } 862 863 if (!send_ack_reply (connection, transaction, 864 message, error)) 865 { 866 bus_matchmaker_remove_rule (matchmaker, rule); 867 goto failed; 868 } 869 870 bus_match_rule_unref (rule); 871 872 return TRUE; 873 874 failed: 875 _DBUS_ASSERT_ERROR_IS_SET (error); 876 if (rule) 877 bus_match_rule_unref (rule); 878 return FALSE; 879 } 880 881 static dbus_bool_t 882 bus_driver_handle_remove_match (DBusConnection *connection, 883 BusTransaction *transaction, 884 DBusMessage *message, 885 DBusError *error) 886 { 887 BusMatchRule *rule; 888 const char *text; 889 DBusString str; 890 BusMatchmaker *matchmaker; 891 892 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 893 894 text = NULL; 895 rule = NULL; 896 897 if (!dbus_message_get_args (message, error, 898 DBUS_TYPE_STRING, &text, 899 DBUS_TYPE_INVALID)) 900 { 901 _dbus_verbose ("No memory to get arguments to RemoveMatch\n"); 902 goto failed; 903 } 904 905 _dbus_string_init_const (&str, text); 906 907 rule = bus_match_rule_parse (connection, &str, error); 908 if (rule == NULL) 909 goto failed; 910 911 /* Send the ack before we remove the rule, since the ack is undone 912 * on transaction cancel, but rule removal isn't. 913 */ 914 if (!send_ack_reply (connection, transaction, 915 message, error)) 916 goto failed; 917 918 matchmaker = bus_connection_get_matchmaker (connection); 919 920 if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error)) 921 goto failed; 922 923 bus_match_rule_unref (rule); 924 925 return TRUE; 926 927 failed: 928 _DBUS_ASSERT_ERROR_IS_SET (error); 929 if (rule) 930 bus_match_rule_unref (rule); 931 return FALSE; 932 } 933 934 static dbus_bool_t 935 bus_driver_handle_get_service_owner (DBusConnection *connection, 936 BusTransaction *transaction, 937 DBusMessage *message, 938 DBusError *error) 939 { 940 const char *text; 941 const char *base_name; 942 DBusString str; 943 BusRegistry *registry; 944 BusService *service; 945 DBusMessage *reply; 946 947 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 948 949 registry = bus_connection_get_registry (connection); 950 951 text = NULL; 952 reply = NULL; 953 954 if (! dbus_message_get_args (message, error, 955 DBUS_TYPE_STRING, &text, 956 DBUS_TYPE_INVALID)) 957 goto failed; 958 959 _dbus_string_init_const (&str, text); 960 service = bus_registry_lookup (registry, &str); 961 if (service == NULL && 962 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) 963 { 964 /* ORG_FREEDESKTOP_DBUS owns itself */ 965 base_name = DBUS_SERVICE_DBUS; 966 } 967 else if (service == NULL) 968 { 969 dbus_set_error (error, 970 DBUS_ERROR_NAME_HAS_NO_OWNER, 971 "Could not get owner of name '%s': no such name", text); 972 goto failed; 973 } 974 else 975 { 976 base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service)); 977 if (base_name == NULL) 978 { 979 /* FIXME - how is this error possible? */ 980 dbus_set_error (error, 981 DBUS_ERROR_FAILED, 982 "Could not determine unique name for '%s'", text); 983 goto failed; 984 } 985 _dbus_assert (*base_name == ':'); 986 } 987 988 _dbus_assert (base_name != NULL); 989 990 reply = dbus_message_new_method_return (message); 991 if (reply == NULL) 992 goto oom; 993 994 if (! dbus_message_append_args (reply, 995 DBUS_TYPE_STRING, &base_name, 996 DBUS_TYPE_INVALID)) 997 goto oom; 998 999 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1000 goto oom; 1001 1002 dbus_message_unref (reply); 1003 1004 return TRUE; 1005 1006 oom: 1007 BUS_SET_OOM (error); 1008 1009 failed: 1010 _DBUS_ASSERT_ERROR_IS_SET (error); 1011 if (reply) 1012 dbus_message_unref (reply); 1013 return FALSE; 1014 } 1015 1016 static dbus_bool_t 1017 bus_driver_handle_list_queued_owners (DBusConnection *connection, 1018 BusTransaction *transaction, 1019 DBusMessage *message, 1020 DBusError *error) 1021 { 1022 const char *text; 1023 DBusList *base_names; 1024 DBusList *link; 1025 DBusString str; 1026 BusRegistry *registry; 1027 BusService *service; 1028 DBusMessage *reply; 1029 DBusMessageIter iter, array_iter; 1030 char *dbus_service_name = DBUS_SERVICE_DBUS; 1031 1032 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1033 1034 registry = bus_connection_get_registry (connection); 1035 1036 base_names = NULL; 1037 text = NULL; 1038 reply = NULL; 1039 1040 if (! dbus_message_get_args (message, error, 1041 DBUS_TYPE_STRING, &text, 1042 DBUS_TYPE_INVALID)) 1043 goto failed; 1044 1045 _dbus_string_init_const (&str, text); 1046 service = bus_registry_lookup (registry, &str); 1047 if (service == NULL && 1048 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) 1049 { 1050 /* ORG_FREEDESKTOP_DBUS owns itself */ 1051 if (! _dbus_list_append (&base_names, dbus_service_name)) 1052 goto oom; 1053 } 1054 else if (service == NULL) 1055 { 1056 dbus_set_error (error, 1057 DBUS_ERROR_NAME_HAS_NO_OWNER, 1058 "Could not get owners of name '%s': no such name", text); 1059 goto failed; 1060 } 1061 else 1062 { 1063 if (!bus_service_list_queued_owners (service, 1064 &base_names, 1065 error)) 1066 goto failed; 1067 } 1068 1069 _dbus_assert (base_names != NULL); 1070 1071 reply = dbus_message_new_method_return (message); 1072 if (reply == NULL) 1073 goto oom; 1074 1075 dbus_message_iter_init_append (reply, &iter); 1076 if (!dbus_message_iter_open_container (&iter, 1077 DBUS_TYPE_ARRAY, 1078 DBUS_TYPE_STRING_AS_STRING, 1079 &array_iter)) 1080 goto oom; 1081 1082 link = _dbus_list_get_first_link (&base_names); 1083 while (link != NULL) 1084 { 1085 char *uname; 1086 1087 _dbus_assert (link->data != NULL); 1088 uname = (char *)link->data; 1089 1090 if (!dbus_message_iter_append_basic (&array_iter, 1091 DBUS_TYPE_STRING, 1092 &uname)) 1093 goto oom; 1094 1095 link = _dbus_list_get_next_link (&base_names, link); 1096 } 1097 1098 if (! dbus_message_iter_close_container (&iter, &array_iter)) 1099 goto oom; 1100 1101 1102 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1103 goto oom; 1104 1105 dbus_message_unref (reply); 1106 1107 return TRUE; 1108 1109 oom: 1110 BUS_SET_OOM (error); 1111 1112 failed: 1113 _DBUS_ASSERT_ERROR_IS_SET (error); 1114 if (reply) 1115 dbus_message_unref (reply); 1116 1117 if (base_names) 1118 _dbus_list_clear (&base_names); 1119 1120 return FALSE; 1121 } 1122 1123 static dbus_bool_t 1124 bus_driver_handle_get_connection_unix_user (DBusConnection *connection, 1125 BusTransaction *transaction, 1126 DBusMessage *message, 1127 DBusError *error) 1128 { 1129 const char *service; 1130 DBusString str; 1131 BusRegistry *registry; 1132 BusService *serv; 1133 DBusConnection *conn; 1134 DBusMessage *reply; 1135 unsigned long uid; 1136 dbus_uint32_t uid32; 1137 1138 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1139 1140 registry = bus_connection_get_registry (connection); 1141 1142 service = NULL; 1143 reply = NULL; 1144 1145 if (! dbus_message_get_args (message, error, 1146 DBUS_TYPE_STRING, &service, 1147 DBUS_TYPE_INVALID)) 1148 goto failed; 1149 1150 _dbus_verbose ("asked for UID of connection %s\n", service); 1151 1152 _dbus_string_init_const (&str, service); 1153 serv = bus_registry_lookup (registry, &str); 1154 if (serv == NULL) 1155 { 1156 dbus_set_error (error, 1157 DBUS_ERROR_NAME_HAS_NO_OWNER, 1158 "Could not get UID of name '%s': no such name", service); 1159 goto failed; 1160 } 1161 1162 conn = bus_service_get_primary_owners_connection (serv); 1163 1164 reply = dbus_message_new_method_return (message); 1165 if (reply == NULL) 1166 goto oom; 1167 1168 if (!dbus_connection_get_unix_user (conn, &uid)) 1169 { 1170 dbus_set_error (error, 1171 DBUS_ERROR_FAILED, 1172 "Could not determine UID for '%s'", service); 1173 goto failed; 1174 } 1175 1176 uid32 = uid; 1177 if (! dbus_message_append_args (reply, 1178 DBUS_TYPE_UINT32, &uid32, 1179 DBUS_TYPE_INVALID)) 1180 goto oom; 1181 1182 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1183 goto oom; 1184 1185 dbus_message_unref (reply); 1186 1187 return TRUE; 1188 1189 oom: 1190 BUS_SET_OOM (error); 1191 1192 failed: 1193 _DBUS_ASSERT_ERROR_IS_SET (error); 1194 if (reply) 1195 dbus_message_unref (reply); 1196 return FALSE; 1197 } 1198 1199 static dbus_bool_t 1200 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, 1201 BusTransaction *transaction, 1202 DBusMessage *message, 1203 DBusError *error) 1204 { 1205 const char *service; 1206 DBusString str; 1207 BusRegistry *registry; 1208 BusService *serv; 1209 DBusConnection *conn; 1210 DBusMessage *reply; 1211 unsigned long pid; 1212 dbus_uint32_t pid32; 1213 1214 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1215 1216 registry = bus_connection_get_registry (connection); 1217 1218 service = NULL; 1219 reply = NULL; 1220 1221 if (! dbus_message_get_args (message, error, 1222 DBUS_TYPE_STRING, &service, 1223 DBUS_TYPE_INVALID)) 1224 goto failed; 1225 1226 _dbus_verbose ("asked for PID of connection %s\n", service); 1227 1228 _dbus_string_init_const (&str, service); 1229 serv = bus_registry_lookup (registry, &str); 1230 if (serv == NULL) 1231 { 1232 dbus_set_error (error, 1233 DBUS_ERROR_NAME_HAS_NO_OWNER, 1234 "Could not get PID of name '%s': no such name", service); 1235 goto failed; 1236 } 1237 1238 conn = bus_service_get_primary_owners_connection (serv); 1239 1240 reply = dbus_message_new_method_return (message); 1241 if (reply == NULL) 1242 goto oom; 1243 1244 if (!dbus_connection_get_unix_process_id (conn, &pid)) 1245 { 1246 dbus_set_error (error, 1247 DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, 1248 "Could not determine PID for '%s'", service); 1249 goto failed; 1250 } 1251 1252 pid32 = pid; 1253 if (! dbus_message_append_args (reply, 1254 DBUS_TYPE_UINT32, &pid32, 1255 DBUS_TYPE_INVALID)) 1256 goto oom; 1257 1258 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1259 goto oom; 1260 1261 dbus_message_unref (reply); 1262 1263 return TRUE; 1264 1265 oom: 1266 BUS_SET_OOM (error); 1267 1268 failed: 1269 _DBUS_ASSERT_ERROR_IS_SET (error); 1270 if (reply) 1271 dbus_message_unref (reply); 1272 return FALSE; 1273 } 1274 1275 static dbus_bool_t 1276 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection, 1277 BusTransaction *transaction, 1278 DBusMessage *message, 1279 DBusError *error) 1280 { 1281 const char *service; 1282 DBusString str; 1283 BusRegistry *registry; 1284 BusService *serv; 1285 DBusConnection *conn; 1286 DBusMessage *reply; 1287 BusSELinuxID *context; 1288 1289 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1290 1291 registry = bus_connection_get_registry (connection); 1292 1293 service = NULL; 1294 reply = NULL; 1295 1296 if (! dbus_message_get_args (message, error, 1297 DBUS_TYPE_STRING, &service, 1298 DBUS_TYPE_INVALID)) 1299 goto failed; 1300 1301 _dbus_verbose ("asked for security context of connection %s\n", service); 1302 1303 _dbus_string_init_const (&str, service); 1304 serv = bus_registry_lookup (registry, &str); 1305 if (serv == NULL) 1306 { 1307 dbus_set_error (error, 1308 DBUS_ERROR_NAME_HAS_NO_OWNER, 1309 "Could not get security context of name '%s': no such name", service); 1310 goto failed; 1311 } 1312 1313 conn = bus_service_get_primary_owners_connection (serv); 1314 1315 reply = dbus_message_new_method_return (message); 1316 if (reply == NULL) 1317 goto oom; 1318 1319 context = bus_connection_get_selinux_id (conn); 1320 if (!context) 1321 { 1322 dbus_set_error (error, 1323 DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, 1324 "Could not determine security context for '%s'", service); 1325 goto failed; 1326 } 1327 1328 if (! bus_selinux_append_context (reply, context, error)) 1329 goto failed; 1330 1331 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1332 goto oom; 1333 1334 dbus_message_unref (reply); 1335 1336 return TRUE; 1337 1338 oom: 1339 BUS_SET_OOM (error); 1340 1341 failed: 1342 _DBUS_ASSERT_ERROR_IS_SET (error); 1343 if (reply) 1344 dbus_message_unref (reply); 1345 return FALSE; 1346 } 1347 1348 static dbus_bool_t 1349 bus_driver_handle_reload_config (DBusConnection *connection, 1350 BusTransaction *transaction, 1351 DBusMessage *message, 1352 DBusError *error) 1353 { 1354 BusContext *context; 1355 DBusMessage *reply; 1356 1357 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1358 1359 reply = NULL; 1360 1361 context = bus_connection_get_context (connection); 1362 if (!bus_context_reload_config (context, error)) 1363 goto failed; 1364 1365 reply = dbus_message_new_method_return (message); 1366 if (reply == NULL) 1367 goto oom; 1368 1369 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1370 goto oom; 1371 1372 dbus_message_unref (reply); 1373 return TRUE; 1374 1375 oom: 1376 BUS_SET_OOM (error); 1377 1378 failed: 1379 _DBUS_ASSERT_ERROR_IS_SET (error); 1380 if (reply) 1381 dbus_message_unref (reply); 1382 return FALSE; 1383 } 1384 1385 /* For speed it might be useful to sort this in order of 1386 * frequency of use (but doesn't matter with only a few items 1387 * anyhow) 1388 */ 1389 struct 1390 { 1391 const char *name; 1392 const char *in_args; 1393 const char *out_args; 1394 dbus_bool_t (* handler) (DBusConnection *connection, 1395 BusTransaction *transaction, 1396 DBusMessage *message, 1397 DBusError *error); 1398 } message_handlers[] = { 1399 { "RequestName", 1400 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING, 1401 DBUS_TYPE_UINT32_AS_STRING, 1402 bus_driver_handle_acquire_service }, 1403 { "ReleaseName", 1404 DBUS_TYPE_STRING_AS_STRING, 1405 DBUS_TYPE_UINT32_AS_STRING, 1406 bus_driver_handle_release_service }, 1407 { "StartServiceByName", 1408 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING, 1409 DBUS_TYPE_UINT32_AS_STRING, 1410 bus_driver_handle_activate_service }, 1411 { "Hello", 1412 "", 1413 DBUS_TYPE_STRING_AS_STRING, 1414 bus_driver_handle_hello }, 1415 { "NameHasOwner", 1416 DBUS_TYPE_STRING_AS_STRING, 1417 DBUS_TYPE_BOOLEAN_AS_STRING, 1418 bus_driver_handle_service_exists }, 1419 { "ListNames", 1420 "", 1421 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1422 bus_driver_handle_list_services }, 1423 { "ListActivatableNames", 1424 "", 1425 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1426 bus_driver_handle_list_activatable_services }, 1427 { "AddMatch", 1428 DBUS_TYPE_STRING_AS_STRING, 1429 "", 1430 bus_driver_handle_add_match }, 1431 { "RemoveMatch", 1432 DBUS_TYPE_STRING_AS_STRING, 1433 "", 1434 bus_driver_handle_remove_match }, 1435 { "GetNameOwner", 1436 DBUS_TYPE_STRING_AS_STRING, 1437 DBUS_TYPE_STRING_AS_STRING, 1438 bus_driver_handle_get_service_owner }, 1439 { "ListQueuedOwners", 1440 DBUS_TYPE_STRING_AS_STRING, 1441 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1442 bus_driver_handle_list_queued_owners }, 1443 { "GetConnectionUnixUser", 1444 DBUS_TYPE_STRING_AS_STRING, 1445 DBUS_TYPE_UINT32_AS_STRING, 1446 bus_driver_handle_get_connection_unix_user }, 1447 { "GetConnectionUnixProcessID", 1448 DBUS_TYPE_STRING_AS_STRING, 1449 DBUS_TYPE_UINT32_AS_STRING, 1450 bus_driver_handle_get_connection_unix_process_id }, 1451 { "GetConnectionSELinuxSecurityContext", 1452 DBUS_TYPE_STRING_AS_STRING, 1453 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, 1454 bus_driver_handle_get_connection_selinux_security_context }, 1455 { "ReloadConfig", 1456 "", 1457 "", 1458 bus_driver_handle_reload_config } 1459 }; 1460 1461 static dbus_bool_t 1462 write_args_for_direction (DBusString *xml, 1463 const char *signature, 1464 dbus_bool_t in) 1465 { 1466 DBusTypeReader typereader; 1467 DBusString sigstr; 1468 int current_type; 1469 1470 _dbus_string_init_const (&sigstr, signature); 1471 _dbus_type_reader_init_types_only (&typereader, &sigstr, 0); 1472 1473 while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID) 1474 { 1475 const DBusString *subsig; 1476 int start, len; 1477 1478 _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len); 1479 if (!_dbus_string_append_printf (xml, " <arg direction=\"%s\" type=\"", 1480 in ? "in" : "out")) 1481 goto oom; 1482 if (!_dbus_string_append_len (xml, 1483 _dbus_string_get_const_data (subsig) + start, 1484 len)) 1485 goto oom; 1486 if (!_dbus_string_append (xml, "\"/>\n")) 1487 goto oom; 1488 1489 _dbus_type_reader_next (&typereader); 1490 } 1491 return TRUE; 1492 oom: 1493 return FALSE; 1494 } 1495 1496 dbus_bool_t 1497 bus_driver_generate_introspect_string (DBusString *xml) 1498 { 1499 int i; 1500 1501 if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) 1502 return FALSE; 1503 if (!_dbus_string_append (xml, "<node>\n")) 1504 return FALSE; 1505 if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE)) 1506 return FALSE; 1507 if (!_dbus_string_append (xml, " <method name=\"Introspect\">\n")) 1508 return FALSE; 1509 if (!_dbus_string_append_printf (xml, " <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING)) 1510 return FALSE; 1511 if (!_dbus_string_append (xml, " </method>\n")) 1512 return FALSE; 1513 if (!_dbus_string_append (xml, " </interface>\n")) 1514 return FALSE; 1515 1516 if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", 1517 DBUS_INTERFACE_DBUS)) 1518 return FALSE; 1519 1520 i = 0; 1521 while (i < _DBUS_N_ELEMENTS (message_handlers)) 1522 { 1523 1524 if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", 1525 message_handlers[i].name)) 1526 return FALSE; 1527 1528 if (!write_args_for_direction (xml, message_handlers[i].in_args, TRUE)) 1529 return FALSE; 1530 1531 if (!write_args_for_direction (xml, message_handlers[i].out_args, FALSE)) 1532 return FALSE; 1533 1534 if (!_dbus_string_append (xml, " </method>\n")) 1535 return FALSE; 1536 1537 ++i; 1538 } 1539 1540 if (!_dbus_string_append_printf (xml, " <signal name=\"NameOwnerChanged\">\n")) 1541 return FALSE; 1542 1543 if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) 1544 return FALSE; 1545 1546 if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) 1547 return FALSE; 1548 1549 if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) 1550 return FALSE; 1551 1552 if (!_dbus_string_append_printf (xml, " </signal>\n")) 1553 return FALSE; 1554 1555 1556 1557 if (!_dbus_string_append_printf (xml, " <signal name=\"NameLost\">\n")) 1558 return FALSE; 1559 1560 if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) 1561 return FALSE; 1562 1563 if (!_dbus_string_append_printf (xml, " </signal>\n")) 1564 return FALSE; 1565 1566 1567 1568 if (!_dbus_string_append_printf (xml, " <signal name=\"NameAcquired\">\n")) 1569 return FALSE; 1570 1571 if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) 1572 return FALSE; 1573 1574 if (!_dbus_string_append_printf (xml, " </signal>\n")) 1575 return FALSE; 1576 1577 if (!_dbus_string_append (xml, " </interface>\n")) 1578 return FALSE; 1579 1580 if (!_dbus_string_append (xml, "</node>\n")) 1581 return FALSE; 1582 1583 return TRUE; 1584 } 1585 1586 static dbus_bool_t 1587 bus_driver_handle_introspect (DBusConnection *connection, 1588 BusTransaction *transaction, 1589 DBusMessage *message, 1590 DBusError *error) 1591 { 1592 DBusString xml; 1593 DBusMessage *reply; 1594 const char *v_STRING; 1595 1596 _dbus_verbose ("Introspect() on bus driver\n"); 1597 1598 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1599 1600 reply = NULL; 1601 1602 if (! dbus_message_get_args (message, error, 1603 DBUS_TYPE_INVALID)) 1604 { 1605 _DBUS_ASSERT_ERROR_IS_SET (error); 1606 return FALSE; 1607 } 1608 1609 if (!_dbus_string_init (&xml)) 1610 { 1611 BUS_SET_OOM (error); 1612 return FALSE; 1613 } 1614 1615 if (!bus_driver_generate_introspect_string (&xml)) 1616 goto oom; 1617 1618 v_STRING = _dbus_string_get_const_data (&xml); 1619 1620 reply = dbus_message_new_method_return (message); 1621 if (reply == NULL) 1622 goto oom; 1623 1624 if (! dbus_message_append_args (reply, 1625 DBUS_TYPE_STRING, &v_STRING, 1626 DBUS_TYPE_INVALID)) 1627 goto oom; 1628 1629 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1630 goto oom; 1631 1632 dbus_message_unref (reply); 1633 _dbus_string_free (&xml); 1634 1635 return TRUE; 1636 1637 oom: 1638 BUS_SET_OOM (error); 1639 1640 if (reply) 1641 dbus_message_unref (reply); 1642 1643 _dbus_string_free (&xml); 1644 1645 return FALSE; 1646 } 1647 1648 dbus_bool_t 1649 bus_driver_handle_message (DBusConnection *connection, 1650 BusTransaction *transaction, 1651 DBusMessage *message, 1652 DBusError *error) 1653 { 1654 const char *name, *sender, *interface; 1655 int i; 1656 1657 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1658 1659 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL) 1660 { 1661 _dbus_verbose ("Driver got a non-method-call message, ignoring\n"); 1662 return TRUE; /* we just ignore this */ 1663 } 1664 1665 if (dbus_message_is_method_call (message, 1666 DBUS_INTERFACE_INTROSPECTABLE, 1667 "Introspect")) 1668 return bus_driver_handle_introspect (connection, transaction, message, error); 1669 1670 interface = dbus_message_get_interface (message); 1671 if (interface == NULL) 1672 interface = DBUS_INTERFACE_DBUS; 1673 1674 _dbus_assert (dbus_message_get_member (message) != NULL); 1675 1676 name = dbus_message_get_member (message); 1677 sender = dbus_message_get_sender (message); 1678 1679 if (strcmp (interface, 1680 DBUS_INTERFACE_DBUS) != 0) 1681 { 1682 _dbus_verbose ("Driver got message to unknown interface \"%s\"\n", 1683 interface); 1684 goto unknown; 1685 } 1686 1687 _dbus_verbose ("Driver got a method call: %s\n", 1688 dbus_message_get_member (message)); 1689 1690 /* security checks should have kept this from getting here */ 1691 _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); 1692 1693 i = 0; 1694 while (i < _DBUS_N_ELEMENTS (message_handlers)) 1695 { 1696 if (strcmp (message_handlers[i].name, name) == 0) 1697 { 1698 _dbus_verbose ("Found driver handler for %s\n", name); 1699 1700 if (!dbus_message_has_signature (message, message_handlers[i].in_args)) 1701 { 1702 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1703 _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n", 1704 name, dbus_message_get_signature (message), 1705 message_handlers[i].in_args); 1706 1707 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 1708 "Call to %s has wrong args (%s, expected %s)\n", 1709 name, dbus_message_get_signature (message), 1710 message_handlers[i].in_args); 1711 _DBUS_ASSERT_ERROR_IS_SET (error); 1712 return FALSE; 1713 } 1714 1715 if ((* message_handlers[i].handler) (connection, transaction, message, error)) 1716 { 1717 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1718 _dbus_verbose ("Driver handler succeeded\n"); 1719 return TRUE; 1720 } 1721 else 1722 { 1723 _DBUS_ASSERT_ERROR_IS_SET (error); 1724 _dbus_verbose ("Driver handler returned failure\n"); 1725 return FALSE; 1726 } 1727 } 1728 1729 ++i; 1730 } 1731 1732 unknown: 1733 _dbus_verbose ("No driver handler for message \"%s\"\n", 1734 name); 1735 1736 dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD, 1737 "%s does not understand message %s", 1738 DBUS_SERVICE_DBUS, name); 1739 1740 return FALSE; 1741 } 1742 1743 void 1744 bus_driver_remove_connection (DBusConnection *connection) 1745 { 1746 /* FIXME 1.0 Does nothing for now, should unregister the connection 1747 * with the bus driver. 1748 */ 1749 } 1750