D-Bus  1.16.2
dbus-bus.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-bus.c Convenience functions for communicating with the bus.
3  *
4  * Copyright (C) 2003 CodeFactory AB
5  * Copyright (C) 2003 Red Hat, Inc.
6  *
7  * SPDX-License-Identifier: AFL-2.1 OR GPL-2.0-or-later
8  *
9  * Licensed under the Academic Free License version 2.1
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  */
26 
27 #include <config.h>
28 #include "dbus-bus.h"
29 #include "dbus-protocol.h"
30 #include "dbus-internals.h"
31 #include "dbus-message.h"
32 #include "dbus-marshal-validate.h"
33 #include "dbus-misc.h"
34 #include "dbus-threads-internal.h"
35 #include "dbus-connection-internal.h"
36 #include "dbus-string.h"
37 
79 typedef struct
80 {
82  char *unique_name;
84  unsigned int is_well_known : 1;
85 } BusData;
86 
90 static dbus_int32_t bus_data_slot = -1;
91 
93 #define N_BUS_TYPES 3
94 
95 /* Protected by _DBUS_LOCK_bus, except during shutdown, which can't safely
96  * be done in a threaded application anyway. */
97 static DBusConnection *bus_connections[N_BUS_TYPES];
98 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
99 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
100 static dbus_bool_t initialized = FALSE;
101 
102 static void
103 addresses_shutdown_func (void *data)
104 {
105  int i;
106 
107  i = 0;
108  while (i < N_BUS_TYPES)
109  {
110  if (bus_connections[i] != NULL)
111  _dbus_warn_check_failed ("dbus_shutdown() called but connections were still live. This probably means the application did not drop all its references to bus connections.");
112 
113  dbus_free (bus_connection_addresses[i]);
114  bus_connection_addresses[i] = NULL;
115  ++i;
116  }
117 
118  activation_bus_type = DBUS_BUS_STARTER;
119 
120  initialized = FALSE;
121 }
122 
123 static dbus_bool_t
124 get_from_env (char **connection_p,
125  const char *env_var)
126 {
127  const char *s;
128 
129  _dbus_assert (*connection_p == NULL);
130 
131  s = _dbus_getenv (env_var);
132  if (s == NULL || *s == '\0')
133  return TRUE; /* successfully didn't use the env var */
134  else
135  {
136  *connection_p = _dbus_strdup (s);
137  return *connection_p != NULL;
138  }
139 }
140 
141 static dbus_bool_t
142 init_session_address (void)
143 {
144  dbus_bool_t retval;
145 
146  retval = FALSE;
147 
148  /* First, look in the environment. This is the normal case on
149  * freedesktop.org/Unix systems. */
150  get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
151  "DBUS_SESSION_BUS_ADDRESS");
152  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
153  {
154  dbus_bool_t supported;
155  DBusString addr;
156  DBusError error = DBUS_ERROR_INIT;
157 
158  if (!_dbus_string_init (&addr))
159  return FALSE;
160 
161  supported = FALSE;
162  /* So it's not in the environment - let's try a platform-specific method.
163  * On MacOS, this involves asking launchd. On Windows (not specified yet)
164  * we might do a COM lookup.
165  * Ignore errors - if we failed, fall back to autolaunch. */
166  retval = _dbus_lookup_session_address (&supported, &addr, &error);
167  if (supported && retval)
168  {
169  retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
170  }
171  else if (supported && !retval)
172  {
173  if (dbus_error_is_set(&error))
174  _dbus_warn ("Dynamic session lookup supported but failed: %s", error.message);
175  else
176  _dbus_warn ("Dynamic session lookup supported but failed silently");
177  }
178  _dbus_string_free (&addr);
179  }
180  else
181  retval = TRUE;
182 
183  if (!retval)
184  return FALSE;
185 
186  /* We have a hard-coded (but compile-time-configurable) fallback address for
187  * the session bus. */
188  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
189  bus_connection_addresses[DBUS_BUS_SESSION] =
190  _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
191 
192  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
193  return FALSE;
194 
195  return TRUE;
196 }
197 
198 static dbus_bool_t
199 init_connections_unlocked (void)
200 {
201  if (!initialized)
202  {
203  const char *s;
204  int i;
205 
206  i = 0;
207  while (i < N_BUS_TYPES)
208  {
209  bus_connections[i] = NULL;
210  ++i;
211  }
212 
213  /* Don't init these twice, we may run this code twice if
214  * init_connections_unlocked() fails midway through.
215  * In practice, each block below should contain only one
216  * "return FALSE" or running through twice may not
217  * work right.
218  */
219 
220  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
221  {
222  _dbus_verbose ("Filling in system bus address...\n");
223 
224  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
225  "DBUS_SYSTEM_BUS_ADDRESS"))
226  return FALSE;
227  }
228 
229 
230  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
231  {
232  /* Use default system bus address if none set in environment */
233  bus_connection_addresses[DBUS_BUS_SYSTEM] =
234  _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
235 
236  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
237  return FALSE;
238 
239  _dbus_verbose (" used default system bus \"%s\"\n",
240  bus_connection_addresses[DBUS_BUS_SYSTEM]);
241  }
242  else
243  _dbus_verbose (" used env var system bus \"%s\"\n",
244  bus_connection_addresses[DBUS_BUS_SYSTEM]);
245 
246  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
247  {
248  _dbus_verbose ("Filling in session bus address...\n");
249 
250  if (!init_session_address ())
251  return FALSE;
252 
253  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
254  bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
255  }
256 
257  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
258  {
259  _dbus_verbose ("Filling in activation bus address...\n");
260 
261  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
262  "DBUS_STARTER_ADDRESS"))
263  return FALSE;
264 
265  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
266  bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
267  }
268 
269 
270  if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
271  {
272  s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
273 
274  if (s != NULL)
275  {
276  _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
277 
278  if (strcmp (s, "system") == 0)
279  activation_bus_type = DBUS_BUS_SYSTEM;
280  else if (strcmp (s, "session") == 0)
281  activation_bus_type = DBUS_BUS_SESSION;
282  }
283  }
284  else
285  {
286  /* Default to the session bus instead if available */
287  if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
288  {
289  bus_connection_addresses[DBUS_BUS_STARTER] =
290  _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
291  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
292  return FALSE;
293  }
294  }
295 
296  /* If we return FALSE we have to be sure that restarting
297  * the above code will work right
298  */
299 
300  if (!_dbus_register_shutdown_func (addresses_shutdown_func,
301  NULL))
302  return FALSE;
303 
304  initialized = TRUE;
305  }
306 
307  return initialized;
308 }
309 
310 static void
311 bus_data_free (void *data)
312 {
313  BusData *bd = data;
314 
315  if (bd->is_well_known)
316  {
317  int i;
318 
319  if (!_DBUS_LOCK (bus))
320  _dbus_assert_not_reached ("global locks should have been initialized "
321  "when we attached bus data");
322 
323  /* We may be stored in more than one slot */
324  /* This should now be impossible - these slots are supposed to
325  * be cleared on disconnect, so should not need to be cleared on
326  * finalize
327  */
328  i = 0;
329  while (i < N_BUS_TYPES)
330  {
331  if (bus_connections[i] == bd->connection)
332  bus_connections[i] = NULL;
333 
334  ++i;
335  }
336  _DBUS_UNLOCK (bus);
337  }
338 
339  dbus_free (bd->unique_name);
340  dbus_free (bd);
341 
342  dbus_connection_free_data_slot (&bus_data_slot);
343 }
344 
345 static BusData*
346 ensure_bus_data (DBusConnection *connection)
347 {
348  BusData *bd;
349 
350  if (!dbus_connection_allocate_data_slot (&bus_data_slot))
351  return NULL;
352 
353  bd = dbus_connection_get_data (connection, bus_data_slot);
354  if (bd == NULL)
355  {
356  bd = dbus_new0 (BusData, 1);
357  if (bd == NULL)
358  {
359  dbus_connection_free_data_slot (&bus_data_slot);
360  return NULL;
361  }
362 
363  bd->connection = connection;
364 
365  if (!dbus_connection_set_data (connection, bus_data_slot, bd,
366  bus_data_free))
367  {
368  dbus_free (bd);
369  dbus_connection_free_data_slot (&bus_data_slot);
370  return NULL;
371  }
372 
373  /* Data slot refcount now held by the BusData */
374  }
375  else
376  {
377  dbus_connection_free_data_slot (&bus_data_slot);
378  }
379 
380  return bd;
381 }
382 
389 void
391 {
392  int i;
393 
394  if (!_DBUS_LOCK (bus))
395  {
396  /* If it was in bus_connections, we would have initialized global locks
397  * when we added it. So, it can't be. */
398  return;
399  }
400 
401  /* We are expecting to have the connection saved in only one of these
402  * slots, but someone could in a pathological case set system and session
403  * bus to the same bus or something. Or set one of them to the starter
404  * bus without setting the starter bus type in the env variable.
405  * So we don't break the loop as soon as we find a match.
406  */
407  for (i = 0; i < N_BUS_TYPES; ++i)
408  {
409  if (bus_connections[i] == connection)
410  {
411  bus_connections[i] = NULL;
412  }
413  }
414 
415  _DBUS_UNLOCK (bus);
416 }
417 
418 static DBusConnection *
419 internal_bus_get (DBusBusType type,
420  dbus_bool_t private,
421  DBusError *error)
422 {
423  const char *address;
424  DBusConnection *connection;
425  BusData *bd;
426  DBusBusType address_type;
427 
428  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
429  _dbus_return_val_if_error_is_set (error, NULL);
430 
431  connection = NULL;
432 
433  if (!_DBUS_LOCK (bus))
434  {
435  _DBUS_SET_OOM (error);
436  /* do not "goto out", that would try to unlock */
437  return NULL;
438  }
439 
440  if (!init_connections_unlocked ())
441  {
442  _DBUS_SET_OOM (error);
443  goto out;
444  }
445 
446  /* We want to use the activation address even if the
447  * activating bus is the session or system bus,
448  * per the spec.
449  */
450  address_type = type;
451 
452  /* Use the real type of the activation bus for getting its
453  * connection, but only if the real type's address is available. (If
454  * the activating bus isn't a well-known bus then
455  * activation_bus_type == DBUS_BUS_STARTER)
456  */
457  if (type == DBUS_BUS_STARTER &&
458  bus_connection_addresses[activation_bus_type] != NULL)
459  type = activation_bus_type;
460 
461  if (!private && bus_connections[type] != NULL)
462  {
463  connection = bus_connections[type];
464  dbus_connection_ref (connection);
465  goto out;
466  }
467 
468  address = bus_connection_addresses[address_type];
469  if (address == NULL)
470  {
472  "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
473  goto out;
474  }
475 
476  if (private)
477  connection = dbus_connection_open_private (address, error);
478  else
479  connection = dbus_connection_open (address, error);
480 
481  if (!connection)
482  {
483  goto out;
484  }
485 
486  if (!dbus_bus_register (connection, error))
487  {
489  dbus_connection_unref (connection);
490  connection = NULL;
491  goto out;
492  }
493 
494  if (!private)
495  {
496  /* store a weak ref to the connection (dbus-connection.c is
497  * supposed to have a strong ref that it drops on disconnect,
498  * since this is a shared connection)
499  */
500  bus_connections[type] = connection;
501  }
502 
503  /* By default we're bound to the lifecycle of
504  * the message bus.
505  */
507  TRUE);
508 
509  if (!_DBUS_LOCK (bus_datas))
510  _dbus_assert_not_reached ("global locks were initialized already");
511 
512  bd = ensure_bus_data (connection);
513  _dbus_assert (bd != NULL); /* it should have been created on
514  register, so OOM not possible */
515  bd->is_well_known = TRUE;
516  _DBUS_UNLOCK (bus_datas);
517 
518 out:
519  /* Return a reference to the caller, or NULL with error set. */
520  if (connection == NULL)
521  _DBUS_ASSERT_ERROR_IS_SET (error);
522 
523  _DBUS_UNLOCK (bus);
524  return connection;
525 }
526 
527  /* end of implementation details docs */
529 
562  DBusError *error)
563 {
564  return internal_bus_get (type, FALSE, error);
565 }
566 
594  DBusError *error)
595 {
596  return internal_bus_get (type, TRUE, error);
597 }
598 
650  DBusError *error)
651 {
652  DBusMessage *message, *reply;
653  char *name;
654  BusData *bd;
655  dbus_bool_t retval;
656 
657  _dbus_return_val_if_fail (connection != NULL, FALSE);
658  _dbus_return_val_if_error_is_set (error, FALSE);
659 
660  retval = FALSE;
661  message = NULL;
662  reply = NULL;
663 
664  if (!_DBUS_LOCK (bus_datas))
665  {
666  _DBUS_SET_OOM (error);
667  /* do not "goto out", that would try to unlock */
668  return FALSE;
669  }
670 
671  bd = ensure_bus_data (connection);
672  if (bd == NULL)
673  {
674  _DBUS_SET_OOM (error);
675  goto out;
676  }
677 
678  if (bd->unique_name != NULL)
679  {
680  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
681  bd->unique_name);
682  /* Success! */
683  retval = TRUE;
684  goto out;
685  }
686 
690  "Hello");
691 
692  if (!message)
693  {
694  _DBUS_SET_OOM (error);
695  goto out;
696  }
697 
698  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
699 
700  if (reply == NULL)
701  goto out;
702  else if (dbus_set_error_from_message (error, reply))
703  goto out;
704  else if (!dbus_message_get_args (reply, error,
705  DBUS_TYPE_STRING, &name,
707  goto out;
708 
709  bd->unique_name = _dbus_strdup (name);
710  if (bd->unique_name == NULL)
711  {
712  _DBUS_SET_OOM (error);
713  goto out;
714  }
715 
716  retval = TRUE;
717 
718  out:
719  _DBUS_UNLOCK (bus_datas);
720 
721  if (message)
722  dbus_message_unref (message);
723 
724  if (reply)
725  dbus_message_unref (reply);
726 
727  if (!retval)
728  _DBUS_ASSERT_ERROR_IS_SET (error);
729 
730  return retval;
731 }
732 
733 
770  const char *unique_name)
771 {
772  BusData *bd;
773  dbus_bool_t success = FALSE;
774 
775  _dbus_return_val_if_fail (connection != NULL, FALSE);
776  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
777 
778  if (!_DBUS_LOCK (bus_datas))
779  {
780  /* do not "goto out", that would try to unlock */
781  return FALSE;
782  }
783 
784  bd = ensure_bus_data (connection);
785  if (bd == NULL)
786  goto out;
787 
788  _dbus_assert (bd->unique_name == NULL);
789 
790  bd->unique_name = _dbus_strdup (unique_name);
791  success = bd->unique_name != NULL;
792 
793 out:
794  _DBUS_UNLOCK (bus_datas);
795 
796  return success;
797 }
798 
817 const char*
819 {
820  BusData *bd;
821  const char *unique_name = NULL;
822 
823  _dbus_return_val_if_fail (connection != NULL, NULL);
824 
825  if (!_DBUS_LOCK (bus_datas))
826  {
827  /* We'd have initialized locks when we gave it its unique name, if it
828  * had one. Don't "goto out", that would try to unlock. */
829  return NULL;
830  }
831 
832  bd = ensure_bus_data (connection);
833  if (bd == NULL)
834  goto out;
835 
836  unique_name = bd->unique_name;
837 
838 out:
839  _DBUS_UNLOCK (bus_datas);
840 
841  return unique_name;
842 }
843 
867 unsigned long
869  const char *name,
870  DBusError *error)
871 {
872  DBusMessage *message, *reply;
873  dbus_uint32_t uid;
874 
875  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
876  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
877  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
878  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
879 
883  "GetConnectionUnixUser");
884 
885  if (message == NULL)
886  {
887  _DBUS_SET_OOM (error);
888  return DBUS_UID_UNSET;
889  }
890 
891  if (!dbus_message_append_args (message,
892  DBUS_TYPE_STRING, &name,
894  {
895  dbus_message_unref (message);
896  _DBUS_SET_OOM (error);
897  return DBUS_UID_UNSET;
898  }
899 
900  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
901  error);
902 
903  dbus_message_unref (message);
904 
905  if (reply == NULL)
906  {
907  _DBUS_ASSERT_ERROR_IS_SET (error);
908  return DBUS_UID_UNSET;
909  }
910 
911  if (dbus_set_error_from_message (error, reply))
912  {
913  _DBUS_ASSERT_ERROR_IS_SET (error);
914  dbus_message_unref (reply);
915  return DBUS_UID_UNSET;
916  }
917 
918  if (!dbus_message_get_args (reply, error,
919  DBUS_TYPE_UINT32, &uid,
921  {
922  _DBUS_ASSERT_ERROR_IS_SET (error);
923  dbus_message_unref (reply);
924  return DBUS_UID_UNSET;
925  }
926 
927  dbus_message_unref (reply);
928 
929  return (unsigned long) uid;
930 }
931 
950 char*
952  DBusError *error)
953 {
954  DBusMessage *message, *reply;
955  char *id;
956  const char *v_STRING;
957 
958  _dbus_return_val_if_fail (connection != NULL, NULL);
959  _dbus_return_val_if_error_is_set (error, NULL);
960 
964  "GetId");
965 
966  if (message == NULL)
967  {
968  _DBUS_SET_OOM (error);
969  return NULL;
970  }
971 
972  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
973  error);
974 
975  dbus_message_unref (message);
976 
977  if (reply == NULL)
978  {
979  _DBUS_ASSERT_ERROR_IS_SET (error);
980  return NULL;
981  }
982 
983  if (dbus_set_error_from_message (error, reply))
984  {
985  _DBUS_ASSERT_ERROR_IS_SET (error);
986  dbus_message_unref (reply);
987  return NULL;
988  }
989 
990  v_STRING = NULL;
991  if (!dbus_message_get_args (reply, error,
992  DBUS_TYPE_STRING, &v_STRING,
994  {
995  _DBUS_ASSERT_ERROR_IS_SET (error);
996  dbus_message_unref (reply);
997  return NULL;
998  }
999 
1000  id = _dbus_strdup (v_STRING); /* may be NULL */
1001 
1002  dbus_message_unref (reply);
1003 
1004  if (id == NULL)
1005  _DBUS_SET_OOM (error);
1006 
1007  /* FIXME it might be nice to cache the ID locally */
1008 
1009  return id;
1010 }
1011 
1114 int
1116  const char *name,
1117  unsigned int flags,
1118  DBusError *error)
1119 {
1120  DBusMessage *message, *reply;
1121  dbus_uint32_t result;
1122 
1123  _dbus_return_val_if_fail (connection != NULL, 0);
1124  _dbus_return_val_if_fail (name != NULL, 0);
1125  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1126  _dbus_return_val_if_error_is_set (error, 0);
1127 
1131  "RequestName");
1132 
1133  if (message == NULL)
1134  {
1135  _DBUS_SET_OOM (error);
1136  return -1;
1137  }
1138 
1139  if (!dbus_message_append_args (message,
1140  DBUS_TYPE_STRING, &name,
1141  DBUS_TYPE_UINT32, &flags,
1143  {
1144  dbus_message_unref (message);
1145  _DBUS_SET_OOM (error);
1146  return -1;
1147  }
1148 
1149  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1150  error);
1151 
1152  dbus_message_unref (message);
1153 
1154  if (reply == NULL)
1155  {
1156  _DBUS_ASSERT_ERROR_IS_SET (error);
1157  return -1;
1158  }
1159 
1160  if (dbus_set_error_from_message (error, reply))
1161  {
1162  _DBUS_ASSERT_ERROR_IS_SET (error);
1163  dbus_message_unref (reply);
1164  return -1;
1165  }
1166 
1167  if (!dbus_message_get_args (reply, error,
1168  DBUS_TYPE_UINT32, &result,
1170  {
1171  _DBUS_ASSERT_ERROR_IS_SET (error);
1172  dbus_message_unref (reply);
1173  return -1;
1174  }
1175 
1176  dbus_message_unref (reply);
1177 
1178  return result;
1179 }
1180 
1181 
1200 int
1202  const char *name,
1203  DBusError *error)
1204 {
1205  DBusMessage *message, *reply;
1206  dbus_uint32_t result;
1207 
1208  _dbus_return_val_if_fail (connection != NULL, 0);
1209  _dbus_return_val_if_fail (name != NULL, 0);
1210  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1211  _dbus_return_val_if_error_is_set (error, 0);
1212 
1216  "ReleaseName");
1217 
1218  if (message == NULL)
1219  {
1220  _DBUS_SET_OOM (error);
1221  return -1;
1222  }
1223 
1224  if (!dbus_message_append_args (message,
1225  DBUS_TYPE_STRING, &name,
1227  {
1228  dbus_message_unref (message);
1229  _DBUS_SET_OOM (error);
1230  return -1;
1231  }
1232 
1233  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1234  error);
1235 
1236  dbus_message_unref (message);
1237 
1238  if (reply == NULL)
1239  {
1240  _DBUS_ASSERT_ERROR_IS_SET (error);
1241  return -1;
1242  }
1243 
1244  if (dbus_set_error_from_message (error, reply))
1245  {
1246  _DBUS_ASSERT_ERROR_IS_SET (error);
1247  dbus_message_unref (reply);
1248  return -1;
1249  }
1250 
1251  if (!dbus_message_get_args (reply, error,
1252  DBUS_TYPE_UINT32, &result,
1254  {
1255  _DBUS_ASSERT_ERROR_IS_SET (error);
1256  dbus_message_unref (reply);
1257  return -1;
1258  }
1259 
1260  dbus_message_unref (reply);
1261 
1262  return result;
1263 }
1264 
1284  const char *name,
1285  DBusError *error)
1286 {
1287  DBusMessage *message, *reply;
1288  dbus_bool_t exists;
1289 
1290  _dbus_return_val_if_fail (connection != NULL, FALSE);
1291  _dbus_return_val_if_fail (name != NULL, FALSE);
1292  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1293  _dbus_return_val_if_error_is_set (error, FALSE);
1294 
1298  "NameHasOwner");
1299  if (message == NULL)
1300  {
1301  _DBUS_SET_OOM (error);
1302  return FALSE;
1303  }
1304 
1305  if (!dbus_message_append_args (message,
1306  DBUS_TYPE_STRING, &name,
1308  {
1309  dbus_message_unref (message);
1310  _DBUS_SET_OOM (error);
1311  return FALSE;
1312  }
1313 
1314  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1315  dbus_message_unref (message);
1316 
1317  if (reply == NULL)
1318  {
1319  _DBUS_ASSERT_ERROR_IS_SET (error);
1320  return FALSE;
1321  }
1322 
1323  if (!dbus_message_get_args (reply, error,
1324  DBUS_TYPE_BOOLEAN, &exists,
1326  {
1327  _DBUS_ASSERT_ERROR_IS_SET (error);
1328  dbus_message_unref (reply);
1329  return FALSE;
1330  }
1331 
1332  dbus_message_unref (reply);
1333  return exists;
1334 }
1335 
1360  const char *name,
1361  dbus_uint32_t flags,
1362  dbus_uint32_t *result,
1363  DBusError *error)
1364 {
1365  DBusMessage *msg;
1366  DBusMessage *reply;
1367 
1368  _dbus_return_val_if_fail (connection != NULL, FALSE);
1369  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1370 
1374  "StartServiceByName");
1375 
1376  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1378  {
1379  dbus_message_unref (msg);
1380  _DBUS_SET_OOM (error);
1381  return FALSE;
1382  }
1383 
1384  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1385  -1, error);
1386  dbus_message_unref (msg);
1387 
1388  if (reply == NULL)
1389  {
1390  _DBUS_ASSERT_ERROR_IS_SET (error);
1391  return FALSE;
1392  }
1393 
1394  if (dbus_set_error_from_message (error, reply))
1395  {
1396  _DBUS_ASSERT_ERROR_IS_SET (error);
1397  dbus_message_unref (reply);
1398  return FALSE;
1399  }
1400 
1401  if (result != NULL &&
1402  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1403  result, DBUS_TYPE_INVALID))
1404  {
1405  _DBUS_ASSERT_ERROR_IS_SET (error);
1406  dbus_message_unref (reply);
1407  return FALSE;
1408  }
1409 
1410  dbus_message_unref (reply);
1411  return TRUE;
1412 }
1413 
1414 static void
1415 send_no_return_values (DBusConnection *connection,
1416  DBusMessage *msg,
1417  DBusError *error)
1418 {
1419  if (error)
1420  {
1421  /* Block to check success codepath */
1422  DBusMessage *reply;
1423 
1424  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1425  -1, error);
1426 
1427  if (reply == NULL)
1428  _DBUS_ASSERT_ERROR_IS_SET (error);
1429  else
1430  dbus_message_unref (reply);
1431  }
1432  else
1433  {
1434  /* Silently-fail nonblocking codepath */
1436  dbus_connection_send (connection, msg, NULL);
1437  }
1438 }
1439 
1528 void
1530  const char *rule,
1531  DBusError *error)
1532 {
1533  DBusMessage *msg;
1534 
1535  _dbus_return_if_fail (rule != NULL);
1536 
1540  "AddMatch");
1541 
1542  if (msg == NULL)
1543  {
1544  _DBUS_SET_OOM (error);
1545  return;
1546  }
1547 
1548  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1550  {
1551  dbus_message_unref (msg);
1552  _DBUS_SET_OOM (error);
1553  return;
1554  }
1555 
1556  send_no_return_values (connection, msg, error);
1557 
1558  dbus_message_unref (msg);
1559 }
1560 
1578 void
1580  const char *rule,
1581  DBusError *error)
1582 {
1583  DBusMessage *msg;
1584 
1585  _dbus_return_if_fail (rule != NULL);
1586 
1590  "RemoveMatch");
1591 
1592  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1594  {
1595  dbus_message_unref (msg);
1596  _DBUS_SET_OOM (error);
1597  return;
1598  }
1599 
1600  send_no_return_values (connection, msg, error);
1601 
1602  dbus_message_unref (msg);
1603 }
1604 
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
const char * message
public error message field
Definition: dbus-errors.h:53
#define NULL
A null pointer, defined appropriately for C or C++.
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:710
int dbus_bus_release_name(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus to unassign the given name from this connection by invoking the ReleaseName method on th...
Definition: dbus-bus.c:1201
DBusConnection * dbus_connection_ref(DBusConnection *connection)
Increments the reference count of a DBusConnection.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
#define DBUS_INTERFACE_DBUS
The interface exported by the object with DBUS_SERVICE_DBUS and DBUS_PATH_DBUS.
Definition: dbus-shared.h:90
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:64
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
dbus_bool_t dbus_connection_set_data(DBusConnection *connection, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusConnection, along with an optional function to be used for freeing the data...
#define N_BUS_TYPES
Number of bus types.
Definition: dbus-bus.c:93
Implementation details of DBusConnection.
The login session bus.
Definition: dbus-shared.h:60
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
Block of message-bus-related data we attach to each DBusConnection used with these convenience functi...
Definition: dbus-bus.c:79
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:148
void dbus_connection_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for connection data slots.
DBusMessage * dbus_connection_send_with_reply_and_block(DBusConnection *connection, DBusMessage *message, int timeout_milliseconds, DBusError *error)
Sends a message and blocks a certain time period while waiting for a reply.
DBusConnection * dbus_connection_open_private(const char *address, DBusError *error)
Opens a new, dedicated connection to a remote address.
Internals of DBusMessage.
int dbus_bus_request_name(DBusConnection *connection, const char *name, unsigned int flags, DBusError *error)
Asks the bus to assign the given name to this connection by invoking the RequestName method on the bu...
Definition: dbus-bus.c:1115
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:60
DBusConnection * connection
Connection we're associated with.
Definition: dbus-bus.c:81
The systemwide bus.
Definition: dbus-shared.h:61
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:37
void dbus_connection_set_exit_on_disconnect(DBusConnection *connection, dbus_bool_t exit_on_disconnect)
Set whether _exit() should be called when the connection receives a disconnect signal.
#define DBUS_PATH_DBUS
The object path used to talk to the bus itself.
Definition: dbus-shared.h:82
dbus_bool_t dbus_connection_send(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial)
Adds a message to the outgoing message queue.
DBusConnection * dbus_bus_get(DBusBusType type, DBusError *error)
Connects to a bus daemon and registers the client with it.
Definition: dbus-bus.c:561
void * dbus_connection_get_data(DBusConnection *connection, dbus_int32_t slot)
Retrieves data previously set with dbus_connection_set_data().
dbus_bool_t dbus_bus_set_unique_name(DBusConnection *connection, const char *unique_name)
Sets the unique name of the connection, as assigned by the message bus.
Definition: dbus-bus.c:769
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
char * unique_name
Unique name of this connection.
Definition: dbus-bus.c:82
dbus_bool_t dbus_connection_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusConnection.
void dbus_bus_remove_match(DBusConnection *connection, const char *rule, DBusError *error)
Removes a previously-added match rule "by value" (the most recently-added identical rule gets removed...
Definition: dbus-bus.c:1579
DBusConnection * dbus_connection_open(const char *address, DBusError *error)
Gets a connection to a remote address.
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Object representing an exception.
Definition: dbus-errors.h:50
void _dbus_bus_notify_shared_connection_disconnected_unlocked(DBusConnection *connection)
Internal function that checks to see if this is a shared connection owned by the bus and if it is unr...
Definition: dbus-bus.c:390
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:356
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:88
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:278
#define TRUE
Expands to "1".
dbus_bool_t dbus_bus_register(DBusConnection *connection, DBusError *error)
Registers a connection with the bus.
Definition: dbus-bus.c:649
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
dbus_bool_t dbus_bus_start_service_by_name(DBusConnection *connection, const char *name, dbus_uint32_t flags, dbus_uint32_t *result, DBusError *error)
Starts a service that will request ownership of the given name.
Definition: dbus-bus.c:1359
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:62
unsigned long dbus_bus_get_unix_user(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus to return the UID the named connection authenticated as, if any.
Definition: dbus-bus.c:868
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:72
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
unsigned int is_well_known
Is one of the well-known connections in our global array.
Definition: dbus-bus.c:84
void _dbus_connection_close_possibly_shared(DBusConnection *connection)
Closes a shared OR private connection, while dbus_connection_close() can only be used on private conn...
The bus that started us, if any.
Definition: dbus-shared.h:62
void dbus_bus_add_match(DBusConnection *connection, const char *rule, DBusError *error)
Adds a match rule to match messages going through the message bus.
Definition: dbus-bus.c:1529
#define FALSE
Expands to "0".
const char * dbus_bus_get_unique_name(DBusConnection *connection)
Gets the unique name of the connection as assigned by the message bus.
Definition: dbus-bus.c:818
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called...
Definition: dbus-memory.c:819
char * dbus_bus_get_id(DBusConnection *connection, DBusError *error)
Asks the bus to return its globally unique ID, as described in the D-Bus specification.
Definition: dbus-bus.c:951
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:686
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero...
#define DBUS_SERVICE_DBUS
The bus name used to talk to the bus itself.
Definition: dbus-shared.h:78
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:197
DBusBusType
Well-known bus types.
Definition: dbus-shared.h:58
DBusConnection * dbus_bus_get_private(DBusBusType type, DBusError *error)
Connects to a bus daemon and registers the client with it as with dbus_bus_register().
Definition: dbus-bus.c:593
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
dbus_bool_t dbus_bus_name_has_owner(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus whether a certain name has an owner.
Definition: dbus-bus.c:1283
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:331