1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* driver.c Bus client (driver)
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
7 * Licensed under the Academic Free License version 2.1
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "activation.h"
27 #include "connection.h"
36 #include <dbus/dbus-string.h>
37 #include <dbus/dbus-internals.h>
38 #include <dbus/dbus-message.h>
39 #include <dbus/dbus-marshal-recursive.h>
42 static DBusConnection *
43 bus_driver_get_conn_helper (DBusConnection *connection,
45 const char *what_we_want,
50 BusRegistry *registry;
55 if (!dbus_message_get_args (message, error,
56 DBUS_TYPE_STRING, &name,
60 _dbus_assert (name != NULL);
61 _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
63 registry = bus_connection_get_registry (connection);
64 _dbus_string_init_const (&str, name);
65 serv = bus_registry_lookup (registry, &str);
69 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
70 "Could not get %s of name '%s': no such name",
75 conn = bus_service_get_primary_owners_connection (serv);
76 _dbus_assert (conn != NULL);
84 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
85 DBusMessage *hello_message,
86 BusTransaction *transaction,
90 bus_driver_send_service_owner_changed (const char *service_name,
91 const char *old_owner,
92 const char *new_owner,
93 BusTransaction *transaction,
98 const char *null_service;
100 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
103 _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
105 old_owner ? old_owner : null_service,
106 new_owner ? new_owner : null_service);
108 message = dbus_message_new_signal (DBUS_PATH_DBUS,
118 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
121 if (!dbus_message_append_args (message,
122 DBUS_TYPE_STRING, &service_name,
123 DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
124 DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
128 _dbus_assert (dbus_message_has_signature (message, "sss"));
130 retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
131 dbus_message_unref (message);
136 dbus_message_unref (message);
142 bus_driver_send_service_lost (DBusConnection *connection,
143 const char *service_name,
144 BusTransaction *transaction,
147 DBusMessage *message;
149 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
151 message = dbus_message_new_signal (DBUS_PATH_DBUS,
161 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
162 !dbus_message_append_args (message,
163 DBUS_TYPE_STRING, &service_name,
166 dbus_message_unref (message);
171 if (!bus_transaction_send_from_driver (transaction, connection, message))
173 dbus_message_unref (message);
179 dbus_message_unref (message);
185 bus_driver_send_service_acquired (DBusConnection *connection,
186 const char *service_name,
187 BusTransaction *transaction,
190 DBusMessage *message;
192 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
194 message = dbus_message_new_signal (DBUS_PATH_DBUS,
204 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
205 !dbus_message_append_args (message,
206 DBUS_TYPE_STRING, &service_name,
209 dbus_message_unref (message);
214 if (!bus_transaction_send_from_driver (transaction, connection, message))
216 dbus_message_unref (message);
222 dbus_message_unref (message);
228 create_unique_client_name (BusRegistry *registry,
231 /* We never want to use the same unique client name twice, because
232 * we want to guarantee that if you send a message to a given unique
233 * name, you always get the same application. So we use two numbers
234 * for INT_MAX * INT_MAX combinations, should be pretty safe against
237 /* FIXME these should be in BusRegistry rather than static vars */
238 static int next_major_number = 0;
239 static int next_minor_number = 0;
242 len = _dbus_string_get_length (str);
246 /* start out with 1-0, go to 1-1, 1-2, 1-3,
247 * up to 1-MAXINT, then 2-0, 2-1, etc.
249 if (next_minor_number <= 0)
251 next_major_number += 1;
252 next_minor_number = 0;
253 if (next_major_number <= 0)
254 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
257 _dbus_assert (next_major_number > 0);
258 _dbus_assert (next_minor_number >= 0);
260 /* appname:MAJOR-MINOR */
262 if (!_dbus_string_append (str, ":"))
265 if (!_dbus_string_append_int (str, next_major_number))
268 if (!_dbus_string_append (str, "."))
271 if (!_dbus_string_append_int (str, next_minor_number))
274 next_minor_number += 1;
276 /* Check if a client with the name exists */
277 if (bus_registry_lookup (registry, str) == NULL)
280 /* drop the number again, try the next one. */
281 _dbus_string_set_length (str, len);
288 bus_driver_handle_hello (DBusConnection *connection,
289 BusTransaction *transaction,
290 DBusMessage *message,
293 DBusString unique_name;
296 BusRegistry *registry;
297 BusConnections *connections;
299 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
301 if (bus_connection_is_active (connection))
303 /* We already handled an Hello message for this connection. */
304 dbus_set_error (error, DBUS_ERROR_FAILED,
305 "Already handled an Hello message");
309 /* Note that when these limits are exceeded we don't disconnect the
310 * connection; we just sort of leave it hanging there until it times
311 * out or disconnects itself or is dropped due to the max number of
312 * incomplete connections. It's even OK if the connection wants to
313 * retry the hello message, we support that.
315 connections = bus_connection_get_connections (connection);
316 if (!bus_connections_check_limits (connections, connection,
319 _DBUS_ASSERT_ERROR_IS_SET (error);
323 if (!_dbus_string_init (&unique_name))
331 registry = bus_connection_get_registry (connection);
333 if (!create_unique_client_name (registry, &unique_name))
339 if (!bus_connection_complete (connection, &unique_name, error))
341 _DBUS_ASSERT_ERROR_IS_SET (error);
345 if (!dbus_message_set_sender (message,
346 bus_connection_get_name (connection)))
352 if (!bus_driver_send_welcome_message (connection, message, transaction, error))
355 /* Create the service */
356 service = bus_registry_ensure (registry,
357 &unique_name, connection, 0, transaction, error);
361 _dbus_assert (bus_connection_is_active (connection));
365 _dbus_string_free (&unique_name);
370 bus_driver_send_welcome_message (DBusConnection *connection,
371 DBusMessage *hello_message,
372 BusTransaction *transaction,
375 DBusMessage *welcome;
378 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
380 name = bus_connection_get_name (connection);
381 _dbus_assert (name != NULL);
383 welcome = dbus_message_new_method_return (hello_message);
390 if (!dbus_message_append_args (welcome,
391 DBUS_TYPE_STRING, &name,
394 dbus_message_unref (welcome);
399 _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
401 if (!bus_transaction_send_from_driver (transaction, connection, welcome))
403 dbus_message_unref (welcome);
409 dbus_message_unref (welcome);
415 bus_driver_handle_list_services (DBusConnection *connection,
416 BusTransaction *transaction,
417 DBusMessage *message,
423 BusRegistry *registry;
425 DBusMessageIter iter;
428 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
430 registry = bus_connection_get_registry (connection);
432 reply = dbus_message_new_method_return (message);
439 if (!bus_registry_list_services (registry, &services, &len))
441 dbus_message_unref (reply);
446 dbus_message_iter_init_append (reply, &iter);
448 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
449 DBUS_TYPE_STRING_AS_STRING,
452 dbus_free_string_array (services);
453 dbus_message_unref (reply);
459 /* Include the bus driver in the list */
460 const char *v_STRING = DBUS_SERVICE_DBUS;
461 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
464 dbus_free_string_array (services);
465 dbus_message_unref (reply);
474 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
477 dbus_free_string_array (services);
478 dbus_message_unref (reply);
485 dbus_free_string_array (services);
487 if (!dbus_message_iter_close_container (&iter, &sub))
489 dbus_message_unref (reply);
494 if (!bus_transaction_send_from_driver (transaction, connection, reply))
496 dbus_message_unref (reply);
502 dbus_message_unref (reply);
508 bus_driver_handle_list_activatable_services (DBusConnection *connection,
509 BusTransaction *transaction,
510 DBusMessage *message,
516 BusActivation *activation;
518 DBusMessageIter iter;
521 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
523 activation = bus_connection_get_activation (connection);
525 reply = dbus_message_new_method_return (message);
532 if (!bus_activation_list_services (activation, &services, &len))
534 dbus_message_unref (reply);
539 dbus_message_iter_init_append (reply, &iter);
541 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
542 DBUS_TYPE_STRING_AS_STRING,
545 dbus_free_string_array (services);
546 dbus_message_unref (reply);
552 /* Include the bus driver in the list */
553 const char *v_STRING = DBUS_SERVICE_DBUS;
554 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
557 dbus_free_string_array (services);
558 dbus_message_unref (reply);
567 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
570 dbus_free_string_array (services);
571 dbus_message_unref (reply);
578 dbus_free_string_array (services);
580 if (!dbus_message_iter_close_container (&iter, &sub))
582 dbus_message_unref (reply);
587 if (!bus_transaction_send_from_driver (transaction, connection, reply))
589 dbus_message_unref (reply);
595 dbus_message_unref (reply);
601 bus_driver_handle_acquire_service (DBusConnection *connection,
602 BusTransaction *transaction,
603 DBusMessage *message,
607 DBusString service_name;
609 dbus_uint32_t service_reply;
612 BusRegistry *registry;
614 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
616 registry = bus_connection_get_registry (connection);
618 if (!dbus_message_get_args (message, error,
619 DBUS_TYPE_STRING, &name,
620 DBUS_TYPE_UINT32, &flags,
624 _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
629 _dbus_string_init_const (&service_name, name);
631 if (!bus_registry_acquire_service (registry, connection,
632 &service_name, flags,
633 &service_reply, transaction,
637 reply = dbus_message_new_method_return (message);
644 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
650 if (!bus_transaction_send_from_driver (transaction, connection, reply))
660 dbus_message_unref (reply);
665 bus_driver_handle_release_service (DBusConnection *connection,
666 BusTransaction *transaction,
667 DBusMessage *message,
671 DBusString service_name;
673 dbus_uint32_t service_reply;
675 BusRegistry *registry;
677 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
679 registry = bus_connection_get_registry (connection);
681 if (!dbus_message_get_args (message, error,
682 DBUS_TYPE_STRING, &name,
686 _dbus_verbose ("Trying to release name %s\n", name);
691 _dbus_string_init_const (&service_name, name);
693 if (!bus_registry_release_service (registry, connection,
694 &service_name, &service_reply,
698 reply = dbus_message_new_method_return (message);
705 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
711 if (!bus_transaction_send_from_driver (transaction, connection, reply))
721 dbus_message_unref (reply);
726 bus_driver_handle_service_exists (DBusConnection *connection,
727 BusTransaction *transaction,
728 DBusMessage *message,
732 DBusString service_name;
734 dbus_bool_t service_exists;
737 BusRegistry *registry;
739 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
741 registry = bus_connection_get_registry (connection);
743 if (!dbus_message_get_args (message, error,
744 DBUS_TYPE_STRING, &name,
750 if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
752 service_exists = TRUE;
756 _dbus_string_init_const (&service_name, name);
757 service = bus_registry_lookup (registry, &service_name);
758 service_exists = service != NULL;
761 reply = dbus_message_new_method_return (message);
768 if (!dbus_message_append_args (reply,
769 DBUS_TYPE_BOOLEAN, &service_exists,
776 if (!bus_transaction_send_from_driver (transaction, connection, reply))
786 dbus_message_unref (reply);
792 bus_driver_handle_activate_service (DBusConnection *connection,
793 BusTransaction *transaction,
794 DBusMessage *message,
800 BusActivation *activation;
802 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
804 activation = bus_connection_get_activation (connection);
806 if (!dbus_message_get_args (message, error,
807 DBUS_TYPE_STRING, &name,
808 DBUS_TYPE_UINT32, &flags,
811 _DBUS_ASSERT_ERROR_IS_SET (error);
812 _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
818 if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
819 message, name, error))
821 _DBUS_ASSERT_ERROR_IS_SET (error);
822 _dbus_verbose ("bus_activation_activate_service() failed\n");
833 send_ack_reply (DBusConnection *connection,
834 BusTransaction *transaction,
835 DBusMessage *message,
840 if (dbus_message_get_no_reply (message))
843 reply = dbus_message_new_method_return (message);
850 if (!bus_transaction_send_from_driver (transaction, connection, reply))
853 dbus_message_unref (reply);
857 dbus_message_unref (reply);
863 bus_driver_handle_update_activation_environment (DBusConnection *connection,
864 BusTransaction *transaction,
865 DBusMessage *message,
869 BusActivation *activation;
870 DBusMessageIter iter;
871 DBusMessageIter dict_iter;
872 DBusMessageIter dict_entry_iter;
875 DBusList *keys, *key_link;
876 DBusList *values, *value_link;
878 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
880 activation = bus_connection_get_activation (connection);
882 dbus_message_iter_init (message, &iter);
884 /* The message signature has already been checked for us,
885 * so let's just assert it's right.
887 #ifndef DBUS_DISABLE_ASSERT
889 int msg_type = dbus_message_iter_get_arg_type (&iter);
891 _dbus_assert (msg_type == DBUS_TYPE_ARRAY);
895 dbus_message_iter_recurse (&iter, &dict_iter);
899 /* Then loop through the sent dictionary, add the location of
900 * the environment keys and values to lists. The result will
901 * be in reverse order, so we don't have to constantly search
902 * for the end of the list in a loop.
906 while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY)
908 dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
910 while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING)
916 dbus_message_iter_get_basic (&dict_entry_iter, &key);
917 dbus_message_iter_next (&dict_entry_iter);
919 value_type = dbus_message_iter_get_arg_type (&dict_entry_iter);
921 if (value_type != DBUS_TYPE_STRING)
924 dbus_message_iter_get_basic (&dict_entry_iter, &value);
926 if (!_dbus_list_append (&keys, key))
932 if (!_dbus_list_append (&values, value))
938 dbus_message_iter_next (&dict_entry_iter);
941 if (key_type != DBUS_TYPE_INVALID)
944 dbus_message_iter_next (&dict_iter);
947 if (array_type != DBUS_TYPE_INVALID)
950 _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values));
954 while (key_link != NULL)
959 key = key_link->data;
960 value = value_link->data;
962 if (!bus_activation_set_environment_variable (activation,
965 _DBUS_ASSERT_ERROR_IS_SET (error);
966 _dbus_verbose ("bus_activation_set_environment_variable() failed\n");
969 key_link = _dbus_list_get_next_link (&keys, key_link);
970 value_link = _dbus_list_get_next_link (&values, value_link);
973 /* FIXME: We can fail early having set only some of the environment variables,
974 * (because of OOM failure). It's sort of hard to fix and it doesn't really
975 * matter, so we're punting for now.
977 if (key_link != NULL)
980 if (!send_ack_reply (connection, transaction,
987 _dbus_list_clear (&keys);
988 _dbus_list_clear (&values);
993 bus_driver_handle_add_match (DBusConnection *connection,
994 BusTransaction *transaction,
995 DBusMessage *message,
1001 BusMatchmaker *matchmaker;
1003 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1008 if (bus_connection_get_n_match_rules (connection) >=
1009 bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
1011 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1012 "Connection \"%s\" is not allowed to add more match rules "
1013 "(increase limits in configuration file if required)",
1014 bus_connection_is_active (connection) ?
1015 bus_connection_get_name (connection) :
1020 if (!dbus_message_get_args (message, error,
1021 DBUS_TYPE_STRING, &text,
1024 _dbus_verbose ("No memory to get arguments to AddMatch\n");
1028 _dbus_string_init_const (&str, text);
1030 rule = bus_match_rule_parse (connection, &str, error);
1034 matchmaker = bus_connection_get_matchmaker (connection);
1036 if (!bus_matchmaker_add_rule (matchmaker, rule))
1038 BUS_SET_OOM (error);
1042 if (!send_ack_reply (connection, transaction,
1045 bus_matchmaker_remove_rule (matchmaker, rule);
1049 bus_match_rule_unref (rule);
1054 _DBUS_ASSERT_ERROR_IS_SET (error);
1056 bus_match_rule_unref (rule);
1061 bus_driver_handle_remove_match (DBusConnection *connection,
1062 BusTransaction *transaction,
1063 DBusMessage *message,
1069 BusMatchmaker *matchmaker;
1071 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1076 if (!dbus_message_get_args (message, error,
1077 DBUS_TYPE_STRING, &text,
1080 _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
1084 _dbus_string_init_const (&str, text);
1086 rule = bus_match_rule_parse (connection, &str, error);
1090 /* Send the ack before we remove the rule, since the ack is undone
1091 * on transaction cancel, but rule removal isn't.
1093 if (!send_ack_reply (connection, transaction,
1097 matchmaker = bus_connection_get_matchmaker (connection);
1099 if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
1102 bus_match_rule_unref (rule);
1107 _DBUS_ASSERT_ERROR_IS_SET (error);
1109 bus_match_rule_unref (rule);
1114 bus_driver_handle_get_service_owner (DBusConnection *connection,
1115 BusTransaction *transaction,
1116 DBusMessage *message,
1120 const char *base_name;
1122 BusRegistry *registry;
1123 BusService *service;
1126 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1128 registry = bus_connection_get_registry (connection);
1133 if (! dbus_message_get_args (message, error,
1134 DBUS_TYPE_STRING, &text,
1138 _dbus_string_init_const (&str, text);
1139 service = bus_registry_lookup (registry, &str);
1140 if (service == NULL &&
1141 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1143 /* ORG_FREEDESKTOP_DBUS owns itself */
1144 base_name = DBUS_SERVICE_DBUS;
1146 else if (service == NULL)
1148 dbus_set_error (error,
1149 DBUS_ERROR_NAME_HAS_NO_OWNER,
1150 "Could not get owner of name '%s': no such name", text);
1155 base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1156 if (base_name == NULL)
1158 /* FIXME - how is this error possible? */
1159 dbus_set_error (error,
1161 "Could not determine unique name for '%s'", text);
1164 _dbus_assert (*base_name == ':');
1167 _dbus_assert (base_name != NULL);
1169 reply = dbus_message_new_method_return (message);
1173 if (! dbus_message_append_args (reply,
1174 DBUS_TYPE_STRING, &base_name,
1178 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1181 dbus_message_unref (reply);
1186 BUS_SET_OOM (error);
1189 _DBUS_ASSERT_ERROR_IS_SET (error);
1191 dbus_message_unref (reply);
1196 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1197 BusTransaction *transaction,
1198 DBusMessage *message,
1202 DBusList *base_names;
1205 BusRegistry *registry;
1206 BusService *service;
1208 DBusMessageIter iter, array_iter;
1209 char *dbus_service_name = DBUS_SERVICE_DBUS;
1211 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1213 registry = bus_connection_get_registry (connection);
1219 if (! dbus_message_get_args (message, error,
1220 DBUS_TYPE_STRING, &text,
1224 _dbus_string_init_const (&str, text);
1225 service = bus_registry_lookup (registry, &str);
1226 if (service == NULL &&
1227 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1229 /* ORG_FREEDESKTOP_DBUS owns itself */
1230 if (! _dbus_list_append (&base_names, dbus_service_name))
1233 else if (service == NULL)
1235 dbus_set_error (error,
1236 DBUS_ERROR_NAME_HAS_NO_OWNER,
1237 "Could not get owners of name '%s': no such name", text);
1242 if (!bus_service_list_queued_owners (service,
1248 _dbus_assert (base_names != NULL);
1250 reply = dbus_message_new_method_return (message);
1254 dbus_message_iter_init_append (reply, &iter);
1255 if (!dbus_message_iter_open_container (&iter,
1257 DBUS_TYPE_STRING_AS_STRING,
1261 link = _dbus_list_get_first_link (&base_names);
1262 while (link != NULL)
1266 _dbus_assert (link->data != NULL);
1267 uname = (char *)link->data;
1269 if (!dbus_message_iter_append_basic (&array_iter,
1274 link = _dbus_list_get_next_link (&base_names, link);
1277 if (! dbus_message_iter_close_container (&iter, &array_iter))
1281 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1284 dbus_message_unref (reply);
1289 BUS_SET_OOM (error);
1292 _DBUS_ASSERT_ERROR_IS_SET (error);
1294 dbus_message_unref (reply);
1297 _dbus_list_clear (&base_names);
1303 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1304 BusTransaction *transaction,
1305 DBusMessage *message,
1308 DBusConnection *conn;
1311 dbus_uint32_t uid32;
1312 const char *service;
1314 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1318 conn = bus_driver_get_conn_helper (connection, message, "UID", &service,
1324 reply = dbus_message_new_method_return (message);
1328 if (!dbus_connection_get_unix_user (conn, &uid))
1330 dbus_set_error (error,
1332 "Could not determine UID for '%s'", service);
1337 if (! dbus_message_append_args (reply,
1338 DBUS_TYPE_UINT32, &uid32,
1342 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1345 dbus_message_unref (reply);
1350 BUS_SET_OOM (error);
1353 _DBUS_ASSERT_ERROR_IS_SET (error);
1355 dbus_message_unref (reply);
1360 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1361 BusTransaction *transaction,
1362 DBusMessage *message,
1365 DBusConnection *conn;
1368 dbus_uint32_t pid32;
1369 const char *service;
1371 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1375 conn = bus_driver_get_conn_helper (connection, message, "PID", &service,
1381 reply = dbus_message_new_method_return (message);
1385 if (!dbus_connection_get_unix_process_id (conn, &pid))
1387 dbus_set_error (error,
1388 DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1389 "Could not determine PID for '%s'", service);
1394 if (! dbus_message_append_args (reply,
1395 DBUS_TYPE_UINT32, &pid32,
1399 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1402 dbus_message_unref (reply);
1407 BUS_SET_OOM (error);
1410 _DBUS_ASSERT_ERROR_IS_SET (error);
1412 dbus_message_unref (reply);
1417 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1418 BusTransaction *transaction,
1419 DBusMessage *message,
1422 DBusConnection *conn;
1425 dbus_uint32_t data_size;
1426 const char *service;
1428 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1432 conn = bus_driver_get_conn_helper (connection, message,
1433 "audit session data", &service, error);
1438 reply = dbus_message_new_method_return (message);
1442 if (!dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) || data == NULL)
1444 dbus_set_error (error,
1445 DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1446 "Could not determine audit session data for '%s'", service);
1450 if (! dbus_message_append_args (reply,
1451 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1455 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1458 dbus_message_unref (reply);
1463 BUS_SET_OOM (error);
1466 _DBUS_ASSERT_ERROR_IS_SET (error);
1468 dbus_message_unref (reply);
1473 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1474 BusTransaction *transaction,
1475 DBusMessage *message,
1478 DBusConnection *conn;
1480 BusSELinuxID *context;
1481 const char *service;
1483 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1487 conn = bus_driver_get_conn_helper (connection, message, "security context",
1493 reply = dbus_message_new_method_return (message);
1497 context = bus_connection_get_selinux_id (conn);
1500 dbus_set_error (error,
1501 DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1502 "Could not determine security context for '%s'", service);
1506 if (! bus_selinux_append_context (reply, context, error))
1509 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1512 dbus_message_unref (reply);
1517 BUS_SET_OOM (error);
1520 _DBUS_ASSERT_ERROR_IS_SET (error);
1522 dbus_message_unref (reply);
1527 bus_driver_handle_reload_config (DBusConnection *connection,
1528 BusTransaction *transaction,
1529 DBusMessage *message,
1532 BusContext *context;
1535 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1539 context = bus_connection_get_context (connection);
1540 if (!bus_context_reload_config (context, error))
1543 reply = dbus_message_new_method_return (message);
1547 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1550 dbus_message_unref (reply);
1554 BUS_SET_OOM (error);
1557 _DBUS_ASSERT_ERROR_IS_SET (error);
1559 dbus_message_unref (reply);
1564 bus_driver_handle_get_id (DBusConnection *connection,
1565 BusTransaction *transaction,
1566 DBusMessage *message,
1569 BusContext *context;
1572 const char *v_STRING;
1574 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1576 if (!_dbus_string_init (&uuid))
1578 BUS_SET_OOM (error);
1584 context = bus_connection_get_context (connection);
1585 if (!bus_context_get_id (context, &uuid))
1588 reply = dbus_message_new_method_return (message);
1592 v_STRING = _dbus_string_get_const_data (&uuid);
1593 if (!dbus_message_append_args (reply,
1594 DBUS_TYPE_STRING, &v_STRING,
1598 _dbus_assert (dbus_message_has_signature (reply, "s"));
1600 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1603 _dbus_string_free (&uuid);
1604 dbus_message_unref (reply);
1608 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1610 BUS_SET_OOM (error);
1613 dbus_message_unref (reply);
1614 _dbus_string_free (&uuid);
1621 const char *in_args;
1622 const char *out_args;
1623 dbus_bool_t (* handler) (DBusConnection *connection,
1624 BusTransaction *transaction,
1625 DBusMessage *message,
1629 /* For speed it might be useful to sort this in order of
1630 * frequency of use (but doesn't matter with only a few items
1633 static const MessageHandler dbus_message_handlers[] = {
1636 DBUS_TYPE_STRING_AS_STRING,
1637 bus_driver_handle_hello },
1639 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1640 DBUS_TYPE_UINT32_AS_STRING,
1641 bus_driver_handle_acquire_service },
1643 DBUS_TYPE_STRING_AS_STRING,
1644 DBUS_TYPE_UINT32_AS_STRING,
1645 bus_driver_handle_release_service },
1646 { "StartServiceByName",
1647 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1648 DBUS_TYPE_UINT32_AS_STRING,
1649 bus_driver_handle_activate_service },
1650 { "UpdateActivationEnvironment",
1651 DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1653 bus_driver_handle_update_activation_environment },
1655 DBUS_TYPE_STRING_AS_STRING,
1656 DBUS_TYPE_BOOLEAN_AS_STRING,
1657 bus_driver_handle_service_exists },
1660 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1661 bus_driver_handle_list_services },
1662 { "ListActivatableNames",
1664 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1665 bus_driver_handle_list_activatable_services },
1667 DBUS_TYPE_STRING_AS_STRING,
1669 bus_driver_handle_add_match },
1671 DBUS_TYPE_STRING_AS_STRING,
1673 bus_driver_handle_remove_match },
1675 DBUS_TYPE_STRING_AS_STRING,
1676 DBUS_TYPE_STRING_AS_STRING,
1677 bus_driver_handle_get_service_owner },
1678 { "ListQueuedOwners",
1679 DBUS_TYPE_STRING_AS_STRING,
1680 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1681 bus_driver_handle_list_queued_owners },
1682 { "GetConnectionUnixUser",
1683 DBUS_TYPE_STRING_AS_STRING,
1684 DBUS_TYPE_UINT32_AS_STRING,
1685 bus_driver_handle_get_connection_unix_user },
1686 { "GetConnectionUnixProcessID",
1687 DBUS_TYPE_STRING_AS_STRING,
1688 DBUS_TYPE_UINT32_AS_STRING,
1689 bus_driver_handle_get_connection_unix_process_id },
1690 { "GetAdtAuditSessionData",
1691 DBUS_TYPE_STRING_AS_STRING,
1692 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1693 bus_driver_handle_get_adt_audit_session_data },
1694 { "GetConnectionSELinuxSecurityContext",
1695 DBUS_TYPE_STRING_AS_STRING,
1696 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1697 bus_driver_handle_get_connection_selinux_security_context },
1701 bus_driver_handle_reload_config },
1704 DBUS_TYPE_STRING_AS_STRING,
1705 bus_driver_handle_get_id },
1706 { NULL, NULL, NULL, NULL }
1709 static dbus_bool_t bus_driver_handle_introspect (DBusConnection *,
1710 BusTransaction *, DBusMessage *, DBusError *);
1712 static const MessageHandler introspectable_message_handlers[] = {
1713 { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
1714 { NULL, NULL, NULL, NULL }
1717 #ifdef DBUS_ENABLE_STATS
1718 static const MessageHandler stats_message_handlers[] = {
1719 { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
1720 { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
1721 { NULL, NULL, NULL, NULL }
1727 const MessageHandler *message_handlers;
1728 const char *extra_introspection;
1731 /* These should ideally be sorted by frequency of use, although it
1732 * probably doesn't matter with this few items */
1733 static InterfaceHandler interface_handlers[] = {
1734 { DBUS_INTERFACE_DBUS, dbus_message_handlers,
1735 " <signal name=\"NameOwnerChanged\">\n"
1736 " <arg type=\"s\"/>\n"
1737 " <arg type=\"s\"/>\n"
1738 " <arg type=\"s\"/>\n"
1740 " <signal name=\"NameLost\">\n"
1741 " <arg type=\"s\"/>\n"
1743 " <signal name=\"NameAcquired\">\n"
1744 " <arg type=\"s\"/>\n"
1746 { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
1747 #ifdef DBUS_ENABLE_STATS
1748 { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
1750 { NULL, NULL, NULL }
1754 write_args_for_direction (DBusString *xml,
1755 const char *signature,
1758 DBusTypeReader typereader;
1762 _dbus_string_init_const (&sigstr, signature);
1763 _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
1765 while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
1767 const DBusString *subsig;
1770 _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
1771 if (!_dbus_string_append_printf (xml, " <arg direction=\"%s\" type=\"",
1774 if (!_dbus_string_append_len (xml,
1775 _dbus_string_get_const_data (subsig) + start,
1778 if (!_dbus_string_append (xml, "\"/>\n"))
1781 _dbus_type_reader_next (&typereader);
1789 bus_driver_generate_introspect_string (DBusString *xml)
1791 const InterfaceHandler *ih;
1792 const MessageHandler *mh;
1794 if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
1796 if (!_dbus_string_append (xml, "<node>\n"))
1799 for (ih = interface_handlers; ih->name != NULL; ih++)
1801 if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n",
1805 for (mh = ih->message_handlers; mh->name != NULL; mh++)
1807 if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n",
1811 if (!write_args_for_direction (xml, mh->in_args, TRUE))
1814 if (!write_args_for_direction (xml, mh->out_args, FALSE))
1817 if (!_dbus_string_append (xml, " </method>\n"))
1821 if (ih->extra_introspection != NULL &&
1822 !_dbus_string_append (xml, ih->extra_introspection))
1825 if (!_dbus_string_append (xml, " </interface>\n"))
1829 if (!_dbus_string_append (xml, "</node>\n"))
1836 bus_driver_handle_introspect (DBusConnection *connection,
1837 BusTransaction *transaction,
1838 DBusMessage *message,
1843 const char *v_STRING;
1845 _dbus_verbose ("Introspect() on bus driver\n");
1847 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1851 if (! dbus_message_get_args (message, error,
1854 _DBUS_ASSERT_ERROR_IS_SET (error);
1858 if (!_dbus_string_init (&xml))
1860 BUS_SET_OOM (error);
1864 if (!bus_driver_generate_introspect_string (&xml))
1867 v_STRING = _dbus_string_get_const_data (&xml);
1869 reply = dbus_message_new_method_return (message);
1873 if (! dbus_message_append_args (reply,
1874 DBUS_TYPE_STRING, &v_STRING,
1878 if (! bus_transaction_send_from_driver (transaction, connection, reply))
1881 dbus_message_unref (reply);
1882 _dbus_string_free (&xml);
1887 BUS_SET_OOM (error);
1890 dbus_message_unref (reply);
1892 _dbus_string_free (&xml);
1898 bus_driver_handle_message (DBusConnection *connection,
1899 BusTransaction *transaction,
1900 DBusMessage *message,
1903 const char *name, *interface;
1904 const InterfaceHandler *ih;
1905 const MessageHandler *mh;
1906 dbus_bool_t found_interface = FALSE;
1908 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1910 if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
1912 BusContext *context;
1914 context = bus_connection_get_context (connection);
1915 return dbus_activation_systemd_failure(bus_context_get_activation(context), message);
1918 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
1920 _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
1921 return TRUE; /* we just ignore this */
1924 /* may be NULL, which means "any interface will do" */
1925 interface = dbus_message_get_interface (message);
1927 _dbus_assert (dbus_message_get_member (message) != NULL);
1929 name = dbus_message_get_member (message);
1931 _dbus_verbose ("Driver got a method call: %s\n", name);
1933 /* security checks should have kept this from getting here */
1934 #ifndef DBUS_DISABLE_ASSERT
1936 const char *sender = dbus_message_get_sender (message);
1938 _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
1942 for (ih = interface_handlers; ih->name != NULL; ih++)
1944 if (interface != NULL && strcmp (interface, ih->name) != 0)
1947 found_interface = TRUE;
1949 for (mh = ih->message_handlers; mh->name != NULL; mh++)
1951 if (strcmp (mh->name, name) != 0)
1954 _dbus_verbose ("Found driver handler for %s\n", name);
1956 if (!dbus_message_has_signature (message, mh->in_args))
1958 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1959 _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
1960 name, dbus_message_get_signature (message),
1963 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1964 "Call to %s has wrong args (%s, expected %s)\n",
1965 name, dbus_message_get_signature (message),
1967 _DBUS_ASSERT_ERROR_IS_SET (error);
1971 if ((* mh->handler) (connection, transaction, message, error))
1973 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1974 _dbus_verbose ("Driver handler succeeded\n");
1979 _DBUS_ASSERT_ERROR_IS_SET (error);
1980 _dbus_verbose ("Driver handler returned failure\n");
1986 _dbus_verbose ("No driver handler for message \"%s\"\n",
1989 dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
1990 "%s does not understand message %s",
1991 DBUS_SERVICE_DBUS, name);
1997 bus_driver_remove_connection (DBusConnection *connection)
1999 /* FIXME 1.0 Does nothing for now, should unregister the connection
2000 * with the bus driver.