D-Bus  1.8.14
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  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-bus.h"
27 #include "dbus-protocol.h"
28 #include "dbus-internals.h"
29 #include "dbus-message.h"
30 #include "dbus-marshal-validate.h"
31 #include "dbus-misc.h"
32 #include "dbus-threads-internal.h"
33 #include "dbus-connection-internal.h"
34 #include "dbus-string.h"
35 
77 typedef struct
78 {
80  char *unique_name;
82  unsigned int is_well_known : 1;
83 } BusData;
84 
87 static dbus_int32_t bus_data_slot = -1;
88 
90 #define N_BUS_TYPES 3
91 
92 static DBusConnection *bus_connections[N_BUS_TYPES];
93 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
94 
95 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
96 
97 static dbus_bool_t initialized = FALSE;
98 
99 static void
100 addresses_shutdown_func (void *data)
101 {
102  int i;
103 
104  i = 0;
105  while (i < N_BUS_TYPES)
106  {
107  if (bus_connections[i] != NULL)
108  _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.\n");
109 
110  dbus_free (bus_connection_addresses[i]);
111  bus_connection_addresses[i] = NULL;
112  ++i;
113  }
114 
115  activation_bus_type = DBUS_BUS_STARTER;
116 
117  initialized = FALSE;
118 }
119 
120 static dbus_bool_t
121 get_from_env (char **connection_p,
122  const char *env_var)
123 {
124  const char *s;
125 
126  _dbus_assert (*connection_p == NULL);
127 
128  s = _dbus_getenv (env_var);
129  if (s == NULL || *s == '\0')
130  return TRUE; /* successfully didn't use the env var */
131  else
132  {
133  *connection_p = _dbus_strdup (s);
134  return *connection_p != NULL;
135  }
136 }
137 
138 static dbus_bool_t
139 init_session_address (void)
140 {
141  dbus_bool_t retval;
142 
143  retval = FALSE;
144 
145  /* First, look in the environment. This is the normal case on
146  * freedesktop.org/Unix systems. */
147  get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
148  "DBUS_SESSION_BUS_ADDRESS");
149  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
150  {
151  dbus_bool_t supported;
152  DBusString addr;
153  DBusError error = DBUS_ERROR_INIT;
154 
155  if (!_dbus_string_init (&addr))
156  return FALSE;
157 
158  supported = FALSE;
159  /* So it's not in the environment - let's try a platform-specific method.
160  * On MacOS, this involves asking launchd. On Windows (not specified yet)
161  * we might do a COM lookup.
162  * Ignore errors - if we failed, fall back to autolaunch. */
163  retval = _dbus_lookup_session_address (&supported, &addr, &error);
164  if (supported && retval)
165  {
166  retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
167  }
168  else if (supported && !retval)
169  {
170  if (dbus_error_is_set(&error))
171  _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message);
172  else
173  _dbus_warn ("Dynamic session lookup supported but failed silently\n");
174  }
175  _dbus_string_free (&addr);
176  }
177  else
178  retval = TRUE;
179 
180  if (!retval)
181  return FALSE;
182 
183  /* We have a hard-coded (but compile-time-configurable) fallback address for
184  * the session bus. */
185  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
186  bus_connection_addresses[DBUS_BUS_SESSION] =
187  _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
188 
189  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
190  return FALSE;
191 
192  return TRUE;
193 }
194 
195 static dbus_bool_t
196 init_connections_unlocked (void)
197 {
198  if (!initialized)
199  {
200  const char *s;
201  int i;
202 
203  i = 0;
204  while (i < N_BUS_TYPES)
205  {
206  bus_connections[i] = NULL;
207  ++i;
208  }
209 
210  /* Don't init these twice, we may run this code twice if
211  * init_connections_unlocked() fails midway through.
212  * In practice, each block below should contain only one
213  * "return FALSE" or running through twice may not
214  * work right.
215  */
216 
217  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
218  {
219  _dbus_verbose ("Filling in system bus address...\n");
220 
221  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
222  "DBUS_SYSTEM_BUS_ADDRESS"))
223  return FALSE;
224  }
225 
226 
227  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
228  {
229  /* Use default system bus address if none set in environment */
230  bus_connection_addresses[DBUS_BUS_SYSTEM] =
231  _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
232 
233  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
234  return FALSE;
235 
236  _dbus_verbose (" used default system bus \"%s\"\n",
237  bus_connection_addresses[DBUS_BUS_SYSTEM]);
238  }
239  else
240  _dbus_verbose (" used env var system bus \"%s\"\n",
241  bus_connection_addresses[DBUS_BUS_SYSTEM]);
242 
243  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
244  {
245  _dbus_verbose ("Filling in session bus address...\n");
246 
247  if (!init_session_address ())
248  return FALSE;
249 
250  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
251  bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
252  }
253 
254  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
255  {
256  _dbus_verbose ("Filling in activation bus address...\n");
257 
258  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
259  "DBUS_STARTER_ADDRESS"))
260  return FALSE;
261 
262  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
263  bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
264  }
265 
266 
267  if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
268  {
269  s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
270 
271  if (s != NULL)
272  {
273  _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
274 
275  if (strcmp (s, "system") == 0)
276  activation_bus_type = DBUS_BUS_SYSTEM;
277  else if (strcmp (s, "session") == 0)
278  activation_bus_type = DBUS_BUS_SESSION;
279  }
280  }
281  else
282  {
283  /* Default to the session bus instead if available */
284  if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
285  {
286  bus_connection_addresses[DBUS_BUS_STARTER] =
287  _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
288  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
289  return FALSE;
290  }
291  }
292 
293  /* If we return FALSE we have to be sure that restarting
294  * the above code will work right
295  */
296 
297  if (!_dbus_register_shutdown_func (addresses_shutdown_func,
298  NULL))
299  return FALSE;
300 
301  initialized = TRUE;
302  }
303 
304  return initialized;
305 }
306 
307 static void
308 bus_data_free (void *data)
309 {
310  BusData *bd = data;
311 
312  if (bd->is_well_known)
313  {
314  int i;
315 
316  if (!_DBUS_LOCK (bus))
317  _dbus_assert_not_reached ("global locks should have been initialized "
318  "when we attached bus data");
319 
320  /* We may be stored in more than one slot */
321  /* This should now be impossible - these slots are supposed to
322  * be cleared on disconnect, so should not need to be cleared on
323  * finalize
324  */
325  i = 0;
326  while (i < N_BUS_TYPES)
327  {
328  if (bus_connections[i] == bd->connection)
329  bus_connections[i] = NULL;
330 
331  ++i;
332  }
333  _DBUS_UNLOCK (bus);
334  }
335 
336  dbus_free (bd->unique_name);
337  dbus_free (bd);
338 
339  dbus_connection_free_data_slot (&bus_data_slot);
340 }
341 
342 static BusData*
343 ensure_bus_data (DBusConnection *connection)
344 {
345  BusData *bd;
346 
347  if (!dbus_connection_allocate_data_slot (&bus_data_slot))
348  return NULL;
349 
350  bd = dbus_connection_get_data (connection, bus_data_slot);
351  if (bd == NULL)
352  {
353  bd = dbus_new0 (BusData, 1);
354  if (bd == NULL)
355  {
356  dbus_connection_free_data_slot (&bus_data_slot);
357  return NULL;
358  }
359 
360  bd->connection = connection;
361 
362  if (!dbus_connection_set_data (connection, bus_data_slot, bd,
363  bus_data_free))
364  {
365  dbus_free (bd);
366  dbus_connection_free_data_slot (&bus_data_slot);
367  return NULL;
368  }
369 
370  /* Data slot refcount now held by the BusData */
371  }
372  else
373  {
374  dbus_connection_free_data_slot (&bus_data_slot);
375  }
376 
377  return bd;
378 }
379 
386 void
388 {
389  int i;
390 
391  if (!_DBUS_LOCK (bus))
392  {
393  /* If it was in bus_connections, we would have initialized global locks
394  * when we added it. So, it can't be. */
395  return;
396  }
397 
398  /* We are expecting to have the connection saved in only one of these
399  * slots, but someone could in a pathological case set system and session
400  * bus to the same bus or something. Or set one of them to the starter
401  * bus without setting the starter bus type in the env variable.
402  * So we don't break the loop as soon as we find a match.
403  */
404  for (i = 0; i < N_BUS_TYPES; ++i)
405  {
406  if (bus_connections[i] == connection)
407  {
408  bus_connections[i] = NULL;
409  }
410  }
411 
412  _DBUS_UNLOCK (bus);
413 }
414 
415 static dbus_bool_t
416 internal_register (DBusConnection *connection,
417  int timeout_milliseconds,
418  DBusError *error)
419 {
420  DBusMessage *message, *reply;
421  char *name;
422  BusData *bd;
423  dbus_bool_t retval;
424 
425  _dbus_return_val_if_fail (connection != NULL, FALSE);
426  _dbus_return_val_if_error_is_set (error, FALSE);
427 
428  retval = FALSE;
429  message = NULL;
430  reply = NULL;
431 
432  _DBUS_LOCK (bus_datas);
433 
434  bd = ensure_bus_data (connection);
435  if (bd == NULL)
436  {
437  _DBUS_SET_OOM (error);
438  goto out;
439  }
440 
441  if (bd->unique_name != NULL)
442  {
443  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
444  bd->unique_name);
445  /* Success! */
446  retval = TRUE;
447  goto out;
448  }
449 
453  "Hello");
454 
455  if (!message)
456  {
457  _DBUS_SET_OOM (error);
458  goto out;
459  }
460 
461  reply = dbus_connection_send_with_reply_and_block (connection, message, timeout_milliseconds, error);
462 
463  if (reply == NULL)
464  goto out;
465  else if (dbus_set_error_from_message (error, reply))
466  goto out;
467  else if (!dbus_message_get_args (reply, error,
468  DBUS_TYPE_STRING, &name,
470  goto out;
471 
472  bd->unique_name = _dbus_strdup (name);
473  if (bd->unique_name == NULL)
474  {
475  _DBUS_SET_OOM (error);
476  goto out;
477  }
478 
479  retval = TRUE;
480 
481  out:
482  _DBUS_UNLOCK (bus_datas);
483 
484  if (message)
485  dbus_message_unref (message);
486 
487  if (reply)
488  dbus_message_unref (reply);
489 
490  return retval;
491 }
492 
493 static DBusConnection *
494 internal_open_and_register (const char *address, dbus_bool_t private, int timeout_milliseconds, DBusError *error)
495 {
496  DBusConnection *connection;
497 
498  if (private)
499  connection = dbus_connection_open_private (address, error);
500  else
501  connection = dbus_connection_open (address, error);
502 
503  if (!connection)
504  {
505  goto out;
506  }
507 
508  if (!internal_register (connection, timeout_milliseconds, error))
509  {
511  dbus_connection_unref (connection);
512  connection = NULL;
513  goto out;
514  }
515 
516 out:
517  return connection;
518 }
519 
520 /* When the D-Bus upgrade that moves /var/run/dbus/ to /run/dbus/ is applied,
521  * D-Bus cannot be restarted with the new socket in /run/, because the session
522  * wouldn't be able to cope with it. We end up with a daemon listening on
523  * /var/run/dbus/system_bus_socket, but clients will now try to register
524  * with it on /run/dbus/system_bus_socket, causing the upgrade, and eventually
525  * critical parts of the user's session, to hang.
526  *
527  * The workaround is inelegant, but probably good enough: We allow the initial
528  * attempt to time out quickly and fall back to trying the old default address.
529  * If that fails too, we go back to blocking on the initial address. */
530 
531 #define OLD_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
532 #define INITIAL_TIMEOUT_MILLISECONDS 250
533 #define INCREMENT_TIMEOUT_MILLISECONDS 250
534 #define MAX_TIMEOUT_MILLISECONDS 10000
535 
536 static DBusConnection *
537 internal_open_and_register_with_fallback (const char *address, dbus_bool_t private, DBusError *error)
538 {
539  DBusConnection *connection = NULL;
540  int timeout_milliseconds;
541 
542  for (timeout_milliseconds = INITIAL_TIMEOUT_MILLISECONDS;
543  connection == NULL && timeout_milliseconds < MAX_TIMEOUT_MILLISECONDS;
544  timeout_milliseconds += INCREMENT_TIMEOUT_MILLISECONDS)
545  {
546  connection = internal_open_and_register (address, private, timeout_milliseconds, NULL);
547 
548  if (!connection && !strcmp (address, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS))
549  connection = internal_open_and_register (OLD_SYSTEM_BUS_DEFAULT_ADDRESS, private, timeout_milliseconds, NULL);
550  }
551 
552  if (!connection)
553  {
554  /* We couldn't register with any of the sockets; fall back to original behavior, blocking
555  * forever or returning an error. */
556  connection = internal_open_and_register (address, private, -1, error);
557  }
558 
559  return connection;
560 }
561 
562 static DBusConnection *
563 internal_bus_get (DBusBusType type,
564  dbus_bool_t private,
565  DBusError *error)
566 {
567  const char *address;
568  DBusConnection *connection;
569  BusData *bd;
570  DBusBusType address_type;
571 
572  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
573  _dbus_return_val_if_error_is_set (error, NULL);
574 
575  connection = NULL;
576 
577  if (!_DBUS_LOCK (bus))
578  {
579  _DBUS_SET_OOM (error);
580  /* do not "goto out", that would try to unlock */
581  return NULL;
582  }
583 
584  if (!init_connections_unlocked ())
585  {
586  _DBUS_SET_OOM (error);
587  goto out;
588  }
589 
590  /* We want to use the activation address even if the
591  * activating bus is the session or system bus,
592  * per the spec.
593  */
594  address_type = type;
595 
596  /* Use the real type of the activation bus for getting its
597  * connection, but only if the real type's address is available. (If
598  * the activating bus isn't a well-known bus then
599  * activation_bus_type == DBUS_BUS_STARTER)
600  */
601  if (type == DBUS_BUS_STARTER &&
602  bus_connection_addresses[activation_bus_type] != NULL)
603  type = activation_bus_type;
604 
605  if (!private && bus_connections[type] != NULL)
606  {
607  connection = bus_connections[type];
608  dbus_connection_ref (connection);
609  goto out;
610  }
611 
612  address = bus_connection_addresses[address_type];
613  if (address == NULL)
614  {
616  "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
617  goto out;
618  }
619 
620  connection = internal_open_and_register_with_fallback (address, private, error);
621 
622  if (!connection)
623  {
624  goto out;
625  }
626 
627  if (!private)
628  {
629  /* store a weak ref to the connection (dbus-connection.c is
630  * supposed to have a strong ref that it drops on disconnect,
631  * since this is a shared connection)
632  */
633  bus_connections[type] = connection;
634  }
635 
636  /* By default we're bound to the lifecycle of
637  * the message bus.
638  */
640  TRUE);
641 
642  if (!_DBUS_LOCK (bus_datas))
643  _dbus_assert_not_reached ("global locks were initialized already");
644 
645  bd = ensure_bus_data (connection);
646  _dbus_assert (bd != NULL); /* it should have been created on
647  register, so OOM not possible */
648  bd->is_well_known = TRUE;
649  _DBUS_UNLOCK (bus_datas);
650 
651 out:
652  /* Return a reference to the caller, or NULL with error set. */
653  if (connection == NULL)
654  _DBUS_ASSERT_ERROR_IS_SET (error);
655 
656  _DBUS_UNLOCK (bus);
657  return connection;
658 }
659 
660  /* end of implementation details docs */
662 
695  DBusError *error)
696 {
697  return internal_bus_get (type, FALSE, error);
698 }
699 
727  DBusError *error)
728 {
729  return internal_bus_get (type, TRUE, error);
730 }
731 
783  DBusError *error)
784 {
785  DBusMessage *message, *reply;
786  char *name;
787  BusData *bd;
788  dbus_bool_t retval;
789 
790  _dbus_return_val_if_fail (connection != NULL, FALSE);
791  _dbus_return_val_if_error_is_set (error, FALSE);
792 
793  retval = FALSE;
794  message = NULL;
795  reply = NULL;
796 
797  if (!_DBUS_LOCK (bus_datas))
798  {
799  _DBUS_SET_OOM (error);
800  /* do not "goto out", that would try to unlock */
801  return FALSE;
802  }
803 
804  bd = ensure_bus_data (connection);
805  if (bd == NULL)
806  {
807  _DBUS_SET_OOM (error);
808  goto out;
809  }
810 
811  if (bd->unique_name != NULL)
812  {
813  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
814  bd->unique_name);
815  /* Success! */
816  retval = TRUE;
817  goto out;
818  }
819 
823  "Hello");
824 
825  if (!message)
826  {
827  _DBUS_SET_OOM (error);
828  goto out;
829  }
830 
831  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
832 
833  if (reply == NULL)
834  goto out;
835  else if (dbus_set_error_from_message (error, reply))
836  goto out;
837  else if (!dbus_message_get_args (reply, error,
838  DBUS_TYPE_STRING, &name,
840  goto out;
841 
842  bd->unique_name = _dbus_strdup (name);
843  if (bd->unique_name == NULL)
844  {
845  _DBUS_SET_OOM (error);
846  goto out;
847  }
848 
849  retval = TRUE;
850 
851  out:
852  _DBUS_UNLOCK (bus_datas);
853 
854  if (message)
855  dbus_message_unref (message);
856 
857  if (reply)
858  dbus_message_unref (reply);
859 
860  if (!retval)
861  _DBUS_ASSERT_ERROR_IS_SET (error);
862 
863  return retval;
864 }
865 
866 
903  const char *unique_name)
904 {
905  BusData *bd;
906  dbus_bool_t success = FALSE;
907 
908  _dbus_return_val_if_fail (connection != NULL, FALSE);
909  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
910 
911  if (!_DBUS_LOCK (bus_datas))
912  {
913  /* do not "goto out", that would try to unlock */
914  return FALSE;
915  }
916 
917  bd = ensure_bus_data (connection);
918  if (bd == NULL)
919  goto out;
920 
921  _dbus_assert (bd->unique_name == NULL);
922 
923  bd->unique_name = _dbus_strdup (unique_name);
924  success = bd->unique_name != NULL;
925 
926 out:
927  _DBUS_UNLOCK (bus_datas);
928 
929  return success;
930 }
931 
950 const char*
952 {
953  BusData *bd;
954  const char *unique_name = NULL;
955 
956  _dbus_return_val_if_fail (connection != NULL, NULL);
957 
958  if (!_DBUS_LOCK (bus_datas))
959  {
960  /* We'd have initialized locks when we gave it its unique name, if it
961  * had one. Don't "goto out", that would try to unlock. */
962  return NULL;
963  }
964 
965  bd = ensure_bus_data (connection);
966  if (bd == NULL)
967  goto out;
968 
969  unique_name = bd->unique_name;
970 
971 out:
972  _DBUS_UNLOCK (bus_datas);
973 
974  return unique_name;
975 }
976 
1000 unsigned long
1002  const char *name,
1003  DBusError *error)
1004 {
1005  DBusMessage *message, *reply;
1006  dbus_uint32_t uid;
1007 
1008  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
1009  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
1010  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
1011  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
1012 
1016  "GetConnectionUnixUser");
1017 
1018  if (message == NULL)
1019  {
1020  _DBUS_SET_OOM (error);
1021  return DBUS_UID_UNSET;
1022  }
1023 
1024  if (!dbus_message_append_args (message,
1025  DBUS_TYPE_STRING, &name,
1027  {
1028  dbus_message_unref (message);
1029  _DBUS_SET_OOM (error);
1030  return DBUS_UID_UNSET;
1031  }
1032 
1033  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1034  error);
1035 
1036  dbus_message_unref (message);
1037 
1038  if (reply == NULL)
1039  {
1040  _DBUS_ASSERT_ERROR_IS_SET (error);
1041  return DBUS_UID_UNSET;
1042  }
1043 
1044  if (dbus_set_error_from_message (error, reply))
1045  {
1046  _DBUS_ASSERT_ERROR_IS_SET (error);
1047  dbus_message_unref (reply);
1048  return DBUS_UID_UNSET;
1049  }
1050 
1051  if (!dbus_message_get_args (reply, error,
1052  DBUS_TYPE_UINT32, &uid,
1054  {
1055  _DBUS_ASSERT_ERROR_IS_SET (error);
1056  dbus_message_unref (reply);
1057  return DBUS_UID_UNSET;
1058  }
1059 
1060  dbus_message_unref (reply);
1061 
1062  return (unsigned long) uid;
1063 }
1064 
1083 char*
1085  DBusError *error)
1086 {
1087  DBusMessage *message, *reply;
1088  char *id;
1089  const char *v_STRING;
1090 
1091  _dbus_return_val_if_fail (connection != NULL, NULL);
1092  _dbus_return_val_if_error_is_set (error, NULL);
1093 
1097  "GetId");
1098 
1099  if (message == NULL)
1100  {
1101  _DBUS_SET_OOM (error);
1102  return NULL;
1103  }
1104 
1105  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1106  error);
1107 
1108  dbus_message_unref (message);
1109 
1110  if (reply == NULL)
1111  {
1112  _DBUS_ASSERT_ERROR_IS_SET (error);
1113  return NULL;
1114  }
1115 
1116  if (dbus_set_error_from_message (error, reply))
1117  {
1118  _DBUS_ASSERT_ERROR_IS_SET (error);
1119  dbus_message_unref (reply);
1120  return NULL;
1121  }
1122 
1123  v_STRING = NULL;
1124  if (!dbus_message_get_args (reply, error,
1125  DBUS_TYPE_STRING, &v_STRING,
1127  {
1128  _DBUS_ASSERT_ERROR_IS_SET (error);
1129  dbus_message_unref (reply);
1130  return NULL;
1131  }
1132 
1133  id = _dbus_strdup (v_STRING); /* may be NULL */
1134 
1135  dbus_message_unref (reply);
1136 
1137  if (id == NULL)
1138  _DBUS_SET_OOM (error);
1139 
1140  /* FIXME it might be nice to cache the ID locally */
1141 
1142  return id;
1143 }
1144 
1247 int
1249  const char *name,
1250  unsigned int flags,
1251  DBusError *error)
1252 {
1253  DBusMessage *message, *reply;
1254  dbus_uint32_t result;
1255 
1256  _dbus_return_val_if_fail (connection != NULL, 0);
1257  _dbus_return_val_if_fail (name != NULL, 0);
1258  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1259  _dbus_return_val_if_error_is_set (error, 0);
1260 
1264  "RequestName");
1265 
1266  if (message == NULL)
1267  {
1268  _DBUS_SET_OOM (error);
1269  return -1;
1270  }
1271 
1272  if (!dbus_message_append_args (message,
1273  DBUS_TYPE_STRING, &name,
1274  DBUS_TYPE_UINT32, &flags,
1276  {
1277  dbus_message_unref (message);
1278  _DBUS_SET_OOM (error);
1279  return -1;
1280  }
1281 
1282  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1283  error);
1284 
1285  dbus_message_unref (message);
1286 
1287  if (reply == NULL)
1288  {
1289  _DBUS_ASSERT_ERROR_IS_SET (error);
1290  return -1;
1291  }
1292 
1293  if (dbus_set_error_from_message (error, reply))
1294  {
1295  _DBUS_ASSERT_ERROR_IS_SET (error);
1296  dbus_message_unref (reply);
1297  return -1;
1298  }
1299 
1300  if (!dbus_message_get_args (reply, error,
1301  DBUS_TYPE_UINT32, &result,
1303  {
1304  _DBUS_ASSERT_ERROR_IS_SET (error);
1305  dbus_message_unref (reply);
1306  return -1;
1307  }
1308 
1309  dbus_message_unref (reply);
1310 
1311  return result;
1312 }
1313 
1314 
1333 int
1335  const char *name,
1336  DBusError *error)
1337 {
1338  DBusMessage *message, *reply;
1339  dbus_uint32_t result;
1340 
1341  _dbus_return_val_if_fail (connection != NULL, 0);
1342  _dbus_return_val_if_fail (name != NULL, 0);
1343  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1344  _dbus_return_val_if_error_is_set (error, 0);
1345 
1349  "ReleaseName");
1350 
1351  if (message == NULL)
1352  {
1353  _DBUS_SET_OOM (error);
1354  return -1;
1355  }
1356 
1357  if (!dbus_message_append_args (message,
1358  DBUS_TYPE_STRING, &name,
1360  {
1361  dbus_message_unref (message);
1362  _DBUS_SET_OOM (error);
1363  return -1;
1364  }
1365 
1366  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1367  error);
1368 
1369  dbus_message_unref (message);
1370 
1371  if (reply == NULL)
1372  {
1373  _DBUS_ASSERT_ERROR_IS_SET (error);
1374  return -1;
1375  }
1376 
1377  if (dbus_set_error_from_message (error, reply))
1378  {
1379  _DBUS_ASSERT_ERROR_IS_SET (error);
1380  dbus_message_unref (reply);
1381  return -1;
1382  }
1383 
1384  if (!dbus_message_get_args (reply, error,
1385  DBUS_TYPE_UINT32, &result,
1387  {
1388  _DBUS_ASSERT_ERROR_IS_SET (error);
1389  dbus_message_unref (reply);
1390  return -1;
1391  }
1392 
1393  dbus_message_unref (reply);
1394 
1395  return result;
1396 }
1397 
1417  const char *name,
1418  DBusError *error)
1419 {
1420  DBusMessage *message, *reply;
1421  dbus_bool_t exists;
1422 
1423  _dbus_return_val_if_fail (connection != NULL, FALSE);
1424  _dbus_return_val_if_fail (name != NULL, FALSE);
1425  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1426  _dbus_return_val_if_error_is_set (error, FALSE);
1427 
1431  "NameHasOwner");
1432  if (message == NULL)
1433  {
1434  _DBUS_SET_OOM (error);
1435  return FALSE;
1436  }
1437 
1438  if (!dbus_message_append_args (message,
1439  DBUS_TYPE_STRING, &name,
1441  {
1442  dbus_message_unref (message);
1443  _DBUS_SET_OOM (error);
1444  return FALSE;
1445  }
1446 
1447  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1448  dbus_message_unref (message);
1449 
1450  if (reply == NULL)
1451  {
1452  _DBUS_ASSERT_ERROR_IS_SET (error);
1453  return FALSE;
1454  }
1455 
1456  if (!dbus_message_get_args (reply, error,
1457  DBUS_TYPE_BOOLEAN, &exists,
1459  {
1460  _DBUS_ASSERT_ERROR_IS_SET (error);
1461  dbus_message_unref (reply);
1462  return FALSE;
1463  }
1464 
1465  dbus_message_unref (reply);
1466  return exists;
1467 }
1468 
1493  const char *name,
1494  dbus_uint32_t flags,
1495  dbus_uint32_t *result,
1496  DBusError *error)
1497 {
1498  DBusMessage *msg;
1499  DBusMessage *reply;
1500 
1501  _dbus_return_val_if_fail (connection != NULL, FALSE);
1502  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1503 
1507  "StartServiceByName");
1508 
1509  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1511  {
1512  dbus_message_unref (msg);
1513  _DBUS_SET_OOM (error);
1514  return FALSE;
1515  }
1516 
1517  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1518  -1, error);
1519  dbus_message_unref (msg);
1520 
1521  if (reply == NULL)
1522  {
1523  _DBUS_ASSERT_ERROR_IS_SET (error);
1524  return FALSE;
1525  }
1526 
1527  if (dbus_set_error_from_message (error, reply))
1528  {
1529  _DBUS_ASSERT_ERROR_IS_SET (error);
1530  dbus_message_unref (reply);
1531  return FALSE;
1532  }
1533 
1534  if (result != NULL &&
1535  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1536  result, DBUS_TYPE_INVALID))
1537  {
1538  _DBUS_ASSERT_ERROR_IS_SET (error);
1539  dbus_message_unref (reply);
1540  return FALSE;
1541  }
1542 
1543  dbus_message_unref (reply);
1544  return TRUE;
1545 }
1546 
1547 static void
1548 send_no_return_values (DBusConnection *connection,
1549  DBusMessage *msg,
1550  DBusError *error)
1551 {
1552  if (error)
1553  {
1554  /* Block to check success codepath */
1555  DBusMessage *reply;
1556 
1557  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1558  -1, error);
1559 
1560  if (reply == NULL)
1561  _DBUS_ASSERT_ERROR_IS_SET (error);
1562  else
1563  dbus_message_unref (reply);
1564  }
1565  else
1566  {
1567  /* Silently-fail nonblocking codepath */
1569  dbus_connection_send (connection, msg, NULL);
1570  }
1571 }
1572 
1661 void
1663  const char *rule,
1664  DBusError *error)
1665 {
1666  DBusMessage *msg;
1667 
1668  _dbus_return_if_fail (rule != NULL);
1669 
1673  "AddMatch");
1674 
1675  if (msg == NULL)
1676  {
1677  _DBUS_SET_OOM (error);
1678  return;
1679  }
1680 
1681  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1683  {
1684  dbus_message_unref (msg);
1685  _DBUS_SET_OOM (error);
1686  return;
1687  }
1688 
1689  send_no_return_values (connection, msg, error);
1690 
1691  dbus_message_unref (msg);
1692 }
1693 
1711 void
1713  const char *rule,
1714  DBusError *error)
1715 {
1716  DBusMessage *msg;
1717 
1718  _dbus_return_if_fail (rule != NULL);
1719 
1723  "RemoveMatch");
1724 
1725  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1727  {
1728  dbus_message_unref (msg);
1729  _DBUS_SET_OOM (error);
1730  return;
1731  }
1732 
1733  send_no_return_values (connection, msg, error);
1734 
1735  dbus_message_unref (msg);
1736 }
1737 
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
const char * message
public error message field
Definition: dbus-errors.h:51
#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:701
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:1334
DBusConnection * dbus_connection_ref(DBusConnection *connection)
Increments the reference count of a DBusConnection.
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define DBUS_INTERFACE_DBUS
The interface exported by the object with DBUS_SERVICE_DBUS and DBUS_PATH_DBUS.
Definition: dbus-shared.h:88
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
void _dbus_warn_check_failed(const char *format,...)
Prints a &quot;critical&quot; 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:90
Implementation details of DBusConnection.
The login session bus.
Definition: dbus-shared.h:58
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
Block of message-bus-related data we attach to each DBusConnection used with these convenience functi...
Definition: dbus-bus.c:77
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:105
void dbus_connection_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for connection data slots.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
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:1248
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
DBusConnection * connection
Connection we&#39;re associated with.
Definition: dbus-bus.c:79
The systemwide bus.
Definition: dbus-shared.h:59
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
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:80
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:694
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:902
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
char * unique_name
Unique name of this connection.
Definition: dbus-bus.c:80
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 &quot;by value&quot; (the most recently-added identical rule gets removed...
Definition: dbus-bus.c:1712
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:48
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:387
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:354
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
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.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define TRUE
Expands to &quot;1&quot;.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t dbus_bus_register(DBusConnection *connection, DBusError *error)
Registers a connection with the bus.
Definition: dbus-bus.c:782
#define DBUS_ERROR_FAILED
A generic error; &quot;something went wrong&quot; - see the error message for more.
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:1492
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
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:1001
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
unsigned int is_well_known
Is one of the well-known connections in our global array.
Definition: dbus-bus.c:82
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:60
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. ...
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:1662
#define FALSE
Expands to &quot;0&quot;.
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:951
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:810
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
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:1084
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:624
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:76
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
DBusBusType
Well-known bus types.
Definition: dbus-shared.h:56
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:726
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:1416
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329