1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* driver.c Bus client (driver)
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the Academic Free License version 2.0
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.
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.
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
25 #include "activation.h"
26 #include "connection.h"
32 #include <dbus/dbus-string.h>
33 #include <dbus/dbus-internals.h>
36 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
37 DBusMessage *hello_message,
38 BusTransaction *transaction,
42 bus_driver_send_service_deleted (const char *service_name,
43 BusTransaction *transaction,
49 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
51 _dbus_verbose ("sending service deleted: %s\n", service_name);
53 message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
54 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
63 if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) ||
64 !dbus_message_append_args (message,
65 DBUS_TYPE_STRING, service_name,
68 dbus_message_unref (message);
73 retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
74 dbus_message_unref (message);
80 bus_driver_send_service_created (const char *service_name,
81 BusTransaction *transaction,
87 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
89 message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
90 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
99 if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
101 dbus_message_unref (message);
106 if (!dbus_message_append_args (message,
107 DBUS_TYPE_STRING, service_name,
110 dbus_message_unref (message);
115 retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
116 dbus_message_unref (message);
122 bus_driver_send_service_lost (DBusConnection *connection,
123 const char *service_name,
124 BusTransaction *transaction,
127 DBusMessage *message;
129 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
131 message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
132 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
141 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
142 !dbus_message_append_args (message,
143 DBUS_TYPE_STRING, service_name,
146 dbus_message_unref (message);
151 if (!bus_transaction_send_from_driver (transaction, connection, message))
153 dbus_message_unref (message);
159 dbus_message_unref (message);
165 bus_driver_send_service_acquired (DBusConnection *connection,
166 const char *service_name,
167 BusTransaction *transaction,
170 DBusMessage *message;
172 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
174 message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
175 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
184 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
185 !dbus_message_append_args (message,
186 DBUS_TYPE_STRING, service_name,
189 dbus_message_unref (message);
194 if (!bus_transaction_send_from_driver (transaction, connection, message))
196 dbus_message_unref (message);
202 dbus_message_unref (message);
208 create_unique_client_name (BusRegistry *registry,
211 /* We never want to use the same unique client name twice, because
212 * we want to guarantee that if you send a message to a given unique
213 * name, you always get the same application. So we use two numbers
214 * for INT_MAX * INT_MAX combinations, should be pretty safe against
217 /* FIXME these should be in BusRegistry rather than static vars */
218 static int next_major_number = 0;
219 static int next_minor_number = 0;
222 len = _dbus_string_get_length (str);
226 /* start out with 1-0, go to 1-1, 1-2, 1-3,
227 * up to 1-MAXINT, then 2-0, 2-1, etc.
229 if (next_minor_number <= 0)
231 next_major_number += 1;
232 next_minor_number = 0;
233 if (next_major_number <= 0)
234 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
237 _dbus_assert (next_major_number > 0);
238 _dbus_assert (next_minor_number >= 0);
240 /* appname:MAJOR-MINOR */
242 if (!_dbus_string_append (str, ":"))
245 if (!_dbus_string_append_int (str, next_major_number))
248 if (!_dbus_string_append (str, "."))
251 if (!_dbus_string_append_int (str, next_minor_number))
254 next_minor_number += 1;
256 /* Check if a client with the name exists */
257 if (bus_registry_lookup (registry, str) == NULL)
260 /* drop the number again, try the next one. */
261 _dbus_string_set_length (str, len);
268 bus_driver_handle_hello (DBusConnection *connection,
269 BusTransaction *transaction,
270 DBusMessage *message,
273 DBusString unique_name;
276 BusRegistry *registry;
277 BusConnections *connections;
279 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
281 /* Note that when these limits are exceeded we don't disconnect the
282 * connection; we just sort of leave it hanging there until it times
283 * out or disconnects itself or is dropped due to the max number of
284 * incomplete connections. It's even OK if the connection wants to
285 * retry the hello message, we support that.
287 connections = bus_connection_get_connections (connection);
288 if (!bus_connections_check_limits (connections, connection,
291 _DBUS_ASSERT_ERROR_IS_SET (error);
295 if (!_dbus_string_init (&unique_name))
303 registry = bus_connection_get_registry (connection);
305 if (!create_unique_client_name (registry, &unique_name))
311 if (!bus_connection_complete (connection, &unique_name, error))
313 _DBUS_ASSERT_ERROR_IS_SET (error);
317 if (!dbus_message_set_sender (message,
318 bus_connection_get_name (connection)))
324 if (!bus_driver_send_welcome_message (connection, message, transaction, error))
327 /* Create the service */
328 service = bus_registry_ensure (registry,
329 &unique_name, connection, transaction, error);
333 bus_service_set_prohibit_replacement (service, TRUE);
335 _dbus_assert (bus_connection_is_active (connection));
339 _dbus_string_free (&unique_name);
344 bus_driver_send_welcome_message (DBusConnection *connection,
345 DBusMessage *hello_message,
346 BusTransaction *transaction,
349 DBusMessage *welcome;
352 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
354 name = bus_connection_get_name (connection);
355 _dbus_assert (name != NULL);
357 welcome = dbus_message_new_method_return (hello_message);
364 if (!dbus_message_append_args (welcome,
365 DBUS_TYPE_STRING, name,
368 dbus_message_unref (welcome);
373 if (!bus_transaction_send_from_driver (transaction, connection, welcome))
375 dbus_message_unref (welcome);
381 dbus_message_unref (welcome);
387 bus_driver_handle_list_services (DBusConnection *connection,
388 BusTransaction *transaction,
389 DBusMessage *message,
395 BusRegistry *registry;
397 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
399 registry = bus_connection_get_registry (connection);
401 reply = dbus_message_new_method_return (message);
408 if (!bus_registry_list_services (registry, &services, &len))
410 dbus_message_unref (reply);
415 if (!dbus_message_append_args (reply,
416 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, services, len,
419 dbus_free_string_array (services);
420 dbus_message_unref (reply);
425 dbus_free_string_array (services);
427 if (!bus_transaction_send_from_driver (transaction, connection, reply))
429 dbus_message_unref (reply);
435 dbus_message_unref (reply);
441 bus_driver_handle_acquire_service (DBusConnection *connection,
442 BusTransaction *transaction,
443 DBusMessage *message,
447 DBusString service_name;
452 BusRegistry *registry;
454 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
456 registry = bus_connection_get_registry (connection);
458 if (!dbus_message_get_args (message, error,
459 DBUS_TYPE_STRING, &name,
460 DBUS_TYPE_UINT32, &flags,
464 _dbus_verbose ("Trying to own service %s with flags 0x%x\n", name, flags);
469 _dbus_string_init_const (&service_name, name);
471 if (!bus_registry_acquire_service (registry, connection,
472 &service_name, flags,
473 &service_reply, transaction,
477 reply = dbus_message_new_method_return (message);
484 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID))
490 if (!bus_transaction_send_from_driver (transaction, connection, reply))
501 dbus_message_unref (reply);
506 bus_driver_handle_service_exists (DBusConnection *connection,
507 BusTransaction *transaction,
508 DBusMessage *message,
512 DBusString service_name;
516 BusRegistry *registry;
518 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
520 registry = bus_connection_get_registry (connection);
522 if (!dbus_message_get_args (message, error,
523 DBUS_TYPE_STRING, &name,
529 _dbus_string_init_const (&service_name, name);
530 service = bus_registry_lookup (registry, &service_name);
532 reply = dbus_message_new_method_return (message);
539 if (!dbus_message_append_args (reply,
540 DBUS_TYPE_UINT32, service != NULL,
547 if (!bus_transaction_send_from_driver (transaction, connection, reply))
557 dbus_message_unref (reply);
564 bus_driver_handle_activate_service (DBusConnection *connection,
565 BusTransaction *transaction,
566 DBusMessage *message,
572 BusActivation *activation;
574 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
576 activation = bus_connection_get_activation (connection);
578 if (!dbus_message_get_args (message, error,
579 DBUS_TYPE_STRING, &name,
580 DBUS_TYPE_UINT32, &flags,
583 _DBUS_ASSERT_ERROR_IS_SET (error);
584 _dbus_verbose ("No memory to get arguments to ActivateService\n");
590 if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
591 message, name, error))
593 _DBUS_ASSERT_ERROR_IS_SET (error);
594 _dbus_verbose ("bus_activation_activate_service() failed\n");
606 send_ack_reply (DBusConnection *connection,
607 BusTransaction *transaction,
608 DBusMessage *message,
613 reply = dbus_message_new_method_return (message);
620 if (!bus_transaction_send_from_driver (transaction, connection, reply))
623 dbus_message_unref (reply);
627 dbus_message_unref (reply);
633 bus_driver_handle_add_match (DBusConnection *connection,
634 BusTransaction *transaction,
635 DBusMessage *message,
641 BusMatchmaker *matchmaker;
643 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
648 if (bus_connection_get_n_match_rules (connection) >=
649 bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
651 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
652 "Connection \"%s\" is not allowed to add more match rules "
653 "(increase limits in configuration file if required)",
654 bus_connection_is_active (connection) ?
655 bus_connection_get_name (connection) :
660 if (!dbus_message_get_args (message, error,
661 DBUS_TYPE_STRING, &text,
664 _dbus_verbose ("No memory to get arguments to AddMatch\n");
668 _dbus_string_init_const (&str, text);
670 rule = bus_match_rule_parse (connection, &str, error);
674 matchmaker = bus_connection_get_matchmaker (connection);
676 if (!bus_matchmaker_add_rule (matchmaker, rule))
682 if (!send_ack_reply (connection, transaction,
685 bus_matchmaker_remove_rule (matchmaker, rule);
689 bus_match_rule_unref (rule);
695 _DBUS_ASSERT_ERROR_IS_SET (error);
697 bus_match_rule_unref (rule);
704 bus_driver_handle_remove_match (DBusConnection *connection,
705 BusTransaction *transaction,
706 DBusMessage *message,
712 BusMatchmaker *matchmaker;
714 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
719 if (!dbus_message_get_args (message, error,
720 DBUS_TYPE_STRING, &text,
723 _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
727 _dbus_string_init_const (&str, text);
729 rule = bus_match_rule_parse (connection, &str, error);
733 /* Send the ack before we remove the rule, since the ack is undone
734 * on transaction cancel, but rule removal isn't.
736 if (!send_ack_reply (connection, transaction,
740 matchmaker = bus_connection_get_matchmaker (connection);
742 if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
745 bus_match_rule_unref (rule);
751 _DBUS_ASSERT_ERROR_IS_SET (error);
753 bus_match_rule_unref (rule);
760 bus_driver_handle_get_service_owner (DBusConnection *connection,
761 BusTransaction *transaction,
762 DBusMessage *message,
766 const char *base_name;
768 BusRegistry *registry;
772 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
774 registry = bus_connection_get_registry (connection);
779 if (! dbus_message_get_args (message, error,
780 DBUS_TYPE_STRING, &text,
784 _dbus_string_init_const (&str, text);
785 service = bus_registry_lookup (registry, &str);
788 dbus_set_error (error,
789 DBUS_ERROR_SERVICE_HAS_NO_OWNER,
790 "Could not get owner of service '%s': no such service", text);
794 base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
795 if (base_name == NULL)
797 dbus_set_error (error,
799 "Could not determine base service for '%s'", text);
802 _dbus_assert (*base_name == ':');
804 reply = dbus_message_new_method_return (message);
808 if (! dbus_message_append_args (reply,
809 DBUS_TYPE_STRING, base_name,
813 if (! bus_transaction_send_from_driver (transaction, connection, reply))
816 dbus_message_unref (reply);
825 _DBUS_ASSERT_ERROR_IS_SET (error);
827 dbus_message_unref (reply);
832 /* For speed it might be useful to sort this in order of
833 * frequency of use (but doesn't matter with only a few items
839 dbus_bool_t (* handler) (DBusConnection *connection,
840 BusTransaction *transaction,
841 DBusMessage *message,
843 } message_handlers[] = {
844 { "AcquireService", bus_driver_handle_acquire_service },
845 { "ActivateService", bus_driver_handle_activate_service },
846 { "Hello", bus_driver_handle_hello },
847 { "ServiceExists", bus_driver_handle_service_exists },
848 { "ListServices", bus_driver_handle_list_services },
849 { "AddMatch", bus_driver_handle_add_match },
850 { "RemoveMatch", bus_driver_handle_remove_match },
851 { "GetServiceOwner", bus_driver_handle_get_service_owner }
855 bus_driver_handle_message (DBusConnection *connection,
856 BusTransaction *transaction,
857 DBusMessage *message,
860 const char *name, *sender;
863 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
865 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
867 _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
868 return TRUE; /* we just ignore this */
871 _dbus_assert (dbus_message_get_interface (message) != NULL);
872 _dbus_assert (dbus_message_get_member (message) != NULL);
874 name = dbus_message_get_member (message);
875 sender = dbus_message_get_sender (message);
877 if (strcmp (dbus_message_get_interface (message),
878 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)
880 _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
881 dbus_message_get_interface (message));
885 _dbus_verbose ("Driver got a method call: %s\n",
886 dbus_message_get_member (message));
888 /* security checks should have kept this from getting here */
889 _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
891 if (dbus_message_get_reply_serial (message) != 0)
893 _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
898 while (i < _DBUS_N_ELEMENTS (message_handlers))
900 if (strcmp (message_handlers[i].name, name) == 0)
902 _dbus_verbose ("Running driver handler for %s\n", name);
903 if ((* message_handlers[i].handler) (connection, transaction, message, error))
905 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
906 _dbus_verbose ("Driver handler succeeded\n");
911 _DBUS_ASSERT_ERROR_IS_SET (error);
912 _dbus_verbose ("Driver handler returned failure\n");
921 _dbus_verbose ("No driver handler for message \"%s\"\n",
924 dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
925 "%s does not understand message %s",
926 DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, name);
932 bus_driver_remove_connection (DBusConnection *connection)
934 /* FIXME Does nothing for now, should unregister the connection
935 * with the bus driver.