D-Bus  1.7.4
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-threads-internal.h"
32 #include "dbus-connection-internal.h"
33 #include "dbus-string.h"
34 
76 typedef struct
77 {
79  char *unique_name;
81  unsigned int is_well_known : 1;
82 } BusData;
83 
86 static dbus_int32_t bus_data_slot = -1;
87 
89 #define N_BUS_TYPES 3
90 
91 static DBusConnection *bus_connections[N_BUS_TYPES];
92 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
93 
94 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
95 
96 static dbus_bool_t initialized = FALSE;
97 
102 
109 _DBUS_DEFINE_GLOBAL_LOCK (bus_datas);
110 
111 static void
112 addresses_shutdown_func (void *data)
113 {
114  int i;
115 
116  i = 0;
117  while (i < N_BUS_TYPES)
118  {
119  if (bus_connections[i] != NULL)
120  _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");
121 
122  dbus_free (bus_connection_addresses[i]);
123  bus_connection_addresses[i] = NULL;
124  ++i;
125  }
126 
127  activation_bus_type = DBUS_BUS_STARTER;
128 
129  initialized = FALSE;
130 }
131 
132 static dbus_bool_t
133 get_from_env (char **connection_p,
134  const char *env_var)
135 {
136  const char *s;
137 
138  _dbus_assert (*connection_p == NULL);
139 
140  s = _dbus_getenv (env_var);
141  if (s == NULL || *s == '\0')
142  return TRUE; /* successfully didn't use the env var */
143  else
144  {
145  *connection_p = _dbus_strdup (s);
146  return *connection_p != NULL;
147  }
148 }
149 
150 static dbus_bool_t
151 init_session_address (void)
152 {
153  dbus_bool_t retval;
154 
155  retval = FALSE;
156 
157  /* First, look in the environment. This is the normal case on
158  * freedesktop.org/Unix systems. */
159  get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
160  "DBUS_SESSION_BUS_ADDRESS");
161  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
162  {
163  dbus_bool_t supported;
164  DBusString addr;
165  DBusError error = DBUS_ERROR_INIT;
166 
167  if (!_dbus_string_init (&addr))
168  return FALSE;
169 
170  supported = FALSE;
171  /* So it's not in the environment - let's try a platform-specific method.
172  * On MacOS, this involves asking launchd. On Windows (not specified yet)
173  * we might do a COM lookup.
174  * Ignore errors - if we failed, fall back to autolaunch. */
175  retval = _dbus_lookup_session_address (&supported, &addr, &error);
176  if (supported && retval)
177  {
178  retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
179  }
180  else if (supported && !retval)
181  {
182  if (dbus_error_is_set(&error))
183  _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message);
184  else
185  _dbus_warn ("Dynamic session lookup supported but failed silently\n");
186  }
187  _dbus_string_free (&addr);
188  }
189  else
190  retval = TRUE;
191 
192  if (!retval)
193  return FALSE;
194 
195  /* We have a hard-coded (but compile-time-configurable) fallback address for
196  * the session bus. */
197  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
198  bus_connection_addresses[DBUS_BUS_SESSION] =
199  _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
200 
201  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
202  return FALSE;
203 
204  return TRUE;
205 }
206 
207 static dbus_bool_t
208 init_connections_unlocked (void)
209 {
210  if (!initialized)
211  {
212  const char *s;
213  int i;
214 
215  i = 0;
216  while (i < N_BUS_TYPES)
217  {
218  bus_connections[i] = NULL;
219  ++i;
220  }
221 
222  /* Don't init these twice, we may run this code twice if
223  * init_connections_unlocked() fails midway through.
224  * In practice, each block below should contain only one
225  * "return FALSE" or running through twice may not
226  * work right.
227  */
228 
229  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
230  {
231  _dbus_verbose ("Filling in system bus address...\n");
232 
233  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
234  "DBUS_SYSTEM_BUS_ADDRESS"))
235  return FALSE;
236  }
237 
238 
239  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
240  {
241  /* Use default system bus address if none set in environment */
242  bus_connection_addresses[DBUS_BUS_SYSTEM] =
243  _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
244 
245  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
246  return FALSE;
247 
248  _dbus_verbose (" used default system bus \"%s\"\n",
249  bus_connection_addresses[DBUS_BUS_SYSTEM]);
250  }
251  else
252  _dbus_verbose (" used env var system bus \"%s\"\n",
253  bus_connection_addresses[DBUS_BUS_SYSTEM]);
254 
255  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
256  {
257  _dbus_verbose ("Filling in session bus address...\n");
258 
259  if (!init_session_address ())
260  return FALSE;
261 
262  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
263  bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
264  }
265 
266  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
267  {
268  _dbus_verbose ("Filling in activation bus address...\n");
269 
270  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
271  "DBUS_STARTER_ADDRESS"))
272  return FALSE;
273 
274  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
275  bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
276  }
277 
278 
279  if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
280  {
281  s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
282 
283  if (s != NULL)
284  {
285  _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
286 
287  if (strcmp (s, "system") == 0)
288  activation_bus_type = DBUS_BUS_SYSTEM;
289  else if (strcmp (s, "session") == 0)
290  activation_bus_type = DBUS_BUS_SESSION;
291  }
292  }
293  else
294  {
295  /* Default to the session bus instead if available */
296  if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
297  {
298  bus_connection_addresses[DBUS_BUS_STARTER] =
299  _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
300  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
301  return FALSE;
302  }
303  }
304 
305  /* If we return FALSE we have to be sure that restarting
306  * the above code will work right
307  */
308 
309  if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
310  return FALSE;
311 
312  if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
313  return FALSE;
314 
315  if (!_dbus_register_shutdown_func (addresses_shutdown_func,
316  NULL))
317  return FALSE;
318 
319  initialized = TRUE;
320  }
321 
322  return initialized;
323 }
324 
325 static void
326 bus_data_free (void *data)
327 {
328  BusData *bd = data;
329 
330  if (bd->is_well_known)
331  {
332  int i;
333  _DBUS_LOCK (bus);
334  /* We may be stored in more than one slot */
335  /* This should now be impossible - these slots are supposed to
336  * be cleared on disconnect, so should not need to be cleared on
337  * finalize
338  */
339  i = 0;
340  while (i < N_BUS_TYPES)
341  {
342  if (bus_connections[i] == bd->connection)
343  bus_connections[i] = NULL;
344 
345  ++i;
346  }
347  _DBUS_UNLOCK (bus);
348  }
349 
350  dbus_free (bd->unique_name);
351  dbus_free (bd);
352 
353  dbus_connection_free_data_slot (&bus_data_slot);
354 }
355 
356 static BusData*
357 ensure_bus_data (DBusConnection *connection)
358 {
359  BusData *bd;
360 
361  if (!dbus_connection_allocate_data_slot (&bus_data_slot))
362  return NULL;
363 
364  bd = dbus_connection_get_data (connection, bus_data_slot);
365  if (bd == NULL)
366  {
367  bd = dbus_new0 (BusData, 1);
368  if (bd == NULL)
369  {
370  dbus_connection_free_data_slot (&bus_data_slot);
371  return NULL;
372  }
373 
374  bd->connection = connection;
375 
376  if (!dbus_connection_set_data (connection, bus_data_slot, bd,
377  bus_data_free))
378  {
379  dbus_free (bd);
380  dbus_connection_free_data_slot (&bus_data_slot);
381  return NULL;
382  }
383 
384  /* Data slot refcount now held by the BusData */
385  }
386  else
387  {
388  dbus_connection_free_data_slot (&bus_data_slot);
389  }
390 
391  return bd;
392 }
393 
400 void
402 {
403  int i;
404 
405  _DBUS_LOCK (bus);
406 
407  /* We are expecting to have the connection saved in only one of these
408  * slots, but someone could in a pathological case set system and session
409  * bus to the same bus or something. Or set one of them to the starter
410  * bus without setting the starter bus type in the env variable.
411  * So we don't break the loop as soon as we find a match.
412  */
413  for (i = 0; i < N_BUS_TYPES; ++i)
414  {
415  if (bus_connections[i] == connection)
416  {
417  bus_connections[i] = NULL;
418  }
419  }
420 
421  _DBUS_UNLOCK (bus);
422 }
423 
424 static dbus_bool_t
425 internal_register (DBusConnection *connection,
426  int timeout_milliseconds,
427  DBusError *error)
428 {
429  DBusMessage *message, *reply;
430  char *name;
431  BusData *bd;
432  dbus_bool_t retval;
433 
434  _dbus_return_val_if_fail (connection != NULL, FALSE);
435  _dbus_return_val_if_error_is_set (error, FALSE);
436 
437  retval = FALSE;
438  message = NULL;
439  reply = NULL;
440 
441  _DBUS_LOCK (bus_datas);
442 
443  bd = ensure_bus_data (connection);
444  if (bd == NULL)
445  {
446  _DBUS_SET_OOM (error);
447  goto out;
448  }
449 
450  if (bd->unique_name != NULL)
451  {
452  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
453  bd->unique_name);
454  /* Success! */
455  retval = TRUE;
456  goto out;
457  }
458 
462  "Hello");
463 
464  if (!message)
465  {
466  _DBUS_SET_OOM (error);
467  goto out;
468  }
469 
470  reply = dbus_connection_send_with_reply_and_block (connection, message, timeout_milliseconds, error);
471 
472  if (reply == NULL)
473  goto out;
474  else if (dbus_set_error_from_message (error, reply))
475  goto out;
476  else if (!dbus_message_get_args (reply, error,
477  DBUS_TYPE_STRING, &name,
479  goto out;
480 
481  bd->unique_name = _dbus_strdup (name);
482  if (bd->unique_name == NULL)
483  {
484  _DBUS_SET_OOM (error);
485  goto out;
486  }
487 
488  retval = TRUE;
489 
490  out:
491  _DBUS_UNLOCK (bus_datas);
492 
493  if (message)
494  dbus_message_unref (message);
495 
496  if (reply)
497  dbus_message_unref (reply);
498 
499  return retval;
500 }
501 
502 static DBusConnection *
503 internal_open_and_register (const char *address, dbus_bool_t private, int timeout_milliseconds, DBusError *error)
504 {
505  DBusConnection *connection;
506 
507  if (private)
508  connection = dbus_connection_open_private (address, error);
509  else
510  connection = dbus_connection_open (address, error);
511 
512  if (!connection)
513  {
514  goto out;
515  }
516 
517  if (!internal_register (connection, timeout_milliseconds, error))
518  {
520  dbus_connection_unref (connection);
521  connection = NULL;
522  goto out;
523  }
524 
525 out:
526  return connection;
527 }
528 
529 /* When the D-Bus upgrade that moves /var/run/dbus/ to /run/dbus/ is applied,
530  * D-Bus cannot be restarted with the new socket in /run/, because the session
531  * wouldn't be able to cope with it. We end up with a daemon listening on
532  * /var/run/dbus/system_bus_socket, but clients will now try to register
533  * with it on /run/dbus/system_bus_socket, causing the upgrade, and eventually
534  * critical parts of the user's session, to hang.
535  *
536  * The workaround is inelegant, but probably good enough: We allow the initial
537  * attempt to time out quickly and fall back to trying the old default address.
538  * If that fails too, we go back to blocking on the initial address. */
539 
540 #define OLD_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
541 #define INITIAL_TIMEOUT_MILLISECONDS 250
542 #define INCREMENT_TIMEOUT_MILLISECONDS 250
543 #define MAX_TIMEOUT_MILLISECONDS 10000
544 
545 static DBusConnection *
546 internal_open_and_register_with_fallback (const char *address, dbus_bool_t private, DBusError *error)
547 {
548  DBusConnection *connection = NULL;
549  int timeout_milliseconds;
550 
551  for (timeout_milliseconds = INITIAL_TIMEOUT_MILLISECONDS;
552  connection == NULL && timeout_milliseconds < MAX_TIMEOUT_MILLISECONDS;
553  timeout_milliseconds += INCREMENT_TIMEOUT_MILLISECONDS)
554  {
555  connection = internal_open_and_register (address, private, timeout_milliseconds, NULL);
556 
557  if (!connection && !strcmp (address, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS))
558  connection = internal_open_and_register (OLD_SYSTEM_BUS_DEFAULT_ADDRESS, private, timeout_milliseconds, NULL);
559  }
560 
561  if (!connection)
562  {
563  /* We couldn't register with any of the sockets; fall back to original behavior, blocking
564  * forever or returning an error. */
565  connection = internal_open_and_register (address, private, -1, error);
566  }
567 
568  return connection;
569 }
570 
571 static DBusConnection *
572 internal_bus_get (DBusBusType type,
573  dbus_bool_t private,
574  DBusError *error)
575 {
576  const char *address;
577  DBusConnection *connection;
578  BusData *bd;
579  DBusBusType address_type;
580 
581  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
582  _dbus_return_val_if_error_is_set (error, NULL);
583 
584  connection = NULL;
585 
586  _DBUS_LOCK (bus);
587 
588  if (!init_connections_unlocked ())
589  {
590  _DBUS_SET_OOM (error);
591  goto out;
592  }
593 
594  /* We want to use the activation address even if the
595  * activating bus is the session or system bus,
596  * per the spec.
597  */
598  address_type = type;
599 
600  /* Use the real type of the activation bus for getting its
601  * connection, but only if the real type's address is available. (If
602  * the activating bus isn't a well-known bus then
603  * activation_bus_type == DBUS_BUS_STARTER)
604  */
605  if (type == DBUS_BUS_STARTER &&
606  bus_connection_addresses[activation_bus_type] != NULL)
607  type = activation_bus_type;
608 
609  if (!private && bus_connections[type] != NULL)
610  {
611  connection = bus_connections[type];
612  dbus_connection_ref (connection);
613  goto out;
614  }
615 
616  address = bus_connection_addresses[address_type];
617  if (address == NULL)
618  {
620  "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
621  goto out;
622  }
623 
624  connection = internal_open_and_register_with_fallback (address, private, error);
625 
626  if (!connection)
627  {
628  goto out;
629  }
630 
631  if (!private)
632  {
633  /* store a weak ref to the connection (dbus-connection.c is
634  * supposed to have a strong ref that it drops on disconnect,
635  * since this is a shared connection)
636  */
637  bus_connections[type] = connection;
638  }
639 
640  /* By default we're bound to the lifecycle of
641  * the message bus.
642  */
644  TRUE);
645 
646  _DBUS_LOCK (bus_datas);
647  bd = ensure_bus_data (connection);
648  _dbus_assert (bd != NULL); /* it should have been created on
649  register, so OOM not possible */
650  bd->is_well_known = TRUE;
651  _DBUS_UNLOCK (bus_datas);
652 
653 out:
654  /* Return a reference to the caller, or NULL with error set. */
655  if (connection == NULL)
656  _DBUS_ASSERT_ERROR_IS_SET (error);
657 
658  _DBUS_UNLOCK (bus);
659  return connection;
660 }
661 
662  /* end of implementation details docs */
664 
697  DBusError *error)
698 {
699  return internal_bus_get (type, FALSE, error);
700 }
701 
729  DBusError *error)
730 {
731  return internal_bus_get (type, TRUE, error);
732 }
733 
785  DBusError *error)
786 {
787  DBusMessage *message, *reply;
788  char *name;
789  BusData *bd;
790  dbus_bool_t retval;
791 
792  _dbus_return_val_if_fail (connection != NULL, FALSE);
793  _dbus_return_val_if_error_is_set (error, FALSE);
794 
795  retval = FALSE;
796  message = NULL;
797  reply = NULL;
798 
799  _DBUS_LOCK (bus_datas);
800 
801  bd = ensure_bus_data (connection);
802  if (bd == NULL)
803  {
804  _DBUS_SET_OOM (error);
805  goto out;
806  }
807 
808  if (bd->unique_name != NULL)
809  {
810  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
811  bd->unique_name);
812  /* Success! */
813  retval = TRUE;
814  goto out;
815  }
816 
820  "Hello");
821 
822  if (!message)
823  {
824  _DBUS_SET_OOM (error);
825  goto out;
826  }
827 
828  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
829 
830  if (reply == NULL)
831  goto out;
832  else if (dbus_set_error_from_message (error, reply))
833  goto out;
834  else if (!dbus_message_get_args (reply, error,
835  DBUS_TYPE_STRING, &name,
837  goto out;
838 
839  bd->unique_name = _dbus_strdup (name);
840  if (bd->unique_name == NULL)
841  {
842  _DBUS_SET_OOM (error);
843  goto out;
844  }
845 
846  retval = TRUE;
847 
848  out:
849  _DBUS_UNLOCK (bus_datas);
850 
851  if (message)
852  dbus_message_unref (message);
853 
854  if (reply)
855  dbus_message_unref (reply);
856 
857  if (!retval)
858  _DBUS_ASSERT_ERROR_IS_SET (error);
859 
860  return retval;
861 }
862 
863 
900  const char *unique_name)
901 {
902  BusData *bd;
903  dbus_bool_t success = FALSE;
904 
905  _dbus_return_val_if_fail (connection != NULL, FALSE);
906  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
907 
908  _DBUS_LOCK (bus_datas);
909 
910  bd = ensure_bus_data (connection);
911  if (bd == NULL)
912  goto out;
913 
914  _dbus_assert (bd->unique_name == NULL);
915 
916  bd->unique_name = _dbus_strdup (unique_name);
917  success = bd->unique_name != NULL;
918 
919 out:
920  _DBUS_UNLOCK (bus_datas);
921 
922  return success;
923 }
924 
943 const char*
945 {
946  BusData *bd;
947  const char *unique_name = NULL;
948 
949  _dbus_return_val_if_fail (connection != NULL, NULL);
950 
951  _DBUS_LOCK (bus_datas);
952 
953  bd = ensure_bus_data (connection);
954  if (bd == NULL)
955  goto out;
956 
957  unique_name = bd->unique_name;
958 
959 out:
960  _DBUS_UNLOCK (bus_datas);
961 
962  return unique_name;
963 }
964 
988 unsigned long
990  const char *name,
991  DBusError *error)
992 {
993  DBusMessage *message, *reply;
994  dbus_uint32_t uid;
995 
996  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
997  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
998  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
999  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
1000 
1004  "GetConnectionUnixUser");
1005 
1006  if (message == NULL)
1007  {
1008  _DBUS_SET_OOM (error);
1009  return DBUS_UID_UNSET;
1010  }
1011 
1012  if (!dbus_message_append_args (message,
1013  DBUS_TYPE_STRING, &name,
1015  {
1016  dbus_message_unref (message);
1017  _DBUS_SET_OOM (error);
1018  return DBUS_UID_UNSET;
1019  }
1020 
1021  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1022  error);
1023 
1024  dbus_message_unref (message);
1025 
1026  if (reply == NULL)
1027  {
1028  _DBUS_ASSERT_ERROR_IS_SET (error);
1029  return DBUS_UID_UNSET;
1030  }
1031 
1032  if (dbus_set_error_from_message (error, reply))
1033  {
1034  _DBUS_ASSERT_ERROR_IS_SET (error);
1035  dbus_message_unref (reply);
1036  return DBUS_UID_UNSET;
1037  }
1038 
1039  if (!dbus_message_get_args (reply, error,
1040  DBUS_TYPE_UINT32, &uid,
1042  {
1043  _DBUS_ASSERT_ERROR_IS_SET (error);
1044  dbus_message_unref (reply);
1045  return DBUS_UID_UNSET;
1046  }
1047 
1048  dbus_message_unref (reply);
1049 
1050  return (unsigned long) uid;
1051 }
1052 
1071 char*
1073  DBusError *error)
1074 {
1075  DBusMessage *message, *reply;
1076  char *id;
1077  const char *v_STRING;
1078 
1079  _dbus_return_val_if_fail (connection != NULL, NULL);
1080  _dbus_return_val_if_error_is_set (error, NULL);
1081 
1085  "GetId");
1086 
1087  if (message == NULL)
1088  {
1089  _DBUS_SET_OOM (error);
1090  return NULL;
1091  }
1092 
1093  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1094  error);
1095 
1096  dbus_message_unref (message);
1097 
1098  if (reply == NULL)
1099  {
1100  _DBUS_ASSERT_ERROR_IS_SET (error);
1101  return NULL;
1102  }
1103 
1104  if (dbus_set_error_from_message (error, reply))
1105  {
1106  _DBUS_ASSERT_ERROR_IS_SET (error);
1107  dbus_message_unref (reply);
1108  return NULL;
1109  }
1110 
1111  v_STRING = NULL;
1112  if (!dbus_message_get_args (reply, error,
1113  DBUS_TYPE_STRING, &v_STRING,
1115  {
1116  _DBUS_ASSERT_ERROR_IS_SET (error);
1117  dbus_message_unref (reply);
1118  return NULL;
1119  }
1120 
1121  id = _dbus_strdup (v_STRING); /* may be NULL */
1122 
1123  dbus_message_unref (reply);
1124 
1125  if (id == NULL)
1126  _DBUS_SET_OOM (error);
1127 
1128  /* FIXME it might be nice to cache the ID locally */
1129 
1130  return id;
1131 }
1132 
1235 int
1237  const char *name,
1238  unsigned int flags,
1239  DBusError *error)
1240 {
1241  DBusMessage *message, *reply;
1242  dbus_uint32_t result;
1243 
1244  _dbus_return_val_if_fail (connection != NULL, 0);
1245  _dbus_return_val_if_fail (name != NULL, 0);
1246  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1247  _dbus_return_val_if_error_is_set (error, 0);
1248 
1252  "RequestName");
1253 
1254  if (message == NULL)
1255  {
1256  _DBUS_SET_OOM (error);
1257  return -1;
1258  }
1259 
1260  if (!dbus_message_append_args (message,
1261  DBUS_TYPE_STRING, &name,
1262  DBUS_TYPE_UINT32, &flags,
1264  {
1265  dbus_message_unref (message);
1266  _DBUS_SET_OOM (error);
1267  return -1;
1268  }
1269 
1270  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1271  error);
1272 
1273  dbus_message_unref (message);
1274 
1275  if (reply == NULL)
1276  {
1277  _DBUS_ASSERT_ERROR_IS_SET (error);
1278  return -1;
1279  }
1280 
1281  if (dbus_set_error_from_message (error, reply))
1282  {
1283  _DBUS_ASSERT_ERROR_IS_SET (error);
1284  dbus_message_unref (reply);
1285  return -1;
1286  }
1287 
1288  if (!dbus_message_get_args (reply, error,
1289  DBUS_TYPE_UINT32, &result,
1291  {
1292  _DBUS_ASSERT_ERROR_IS_SET (error);
1293  dbus_message_unref (reply);
1294  return -1;
1295  }
1296 
1297  dbus_message_unref (reply);
1298 
1299  return result;
1300 }
1301 
1302 
1321 int
1323  const char *name,
1324  DBusError *error)
1325 {
1326  DBusMessage *message, *reply;
1327  dbus_uint32_t result;
1328 
1329  _dbus_return_val_if_fail (connection != NULL, 0);
1330  _dbus_return_val_if_fail (name != NULL, 0);
1331  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1332  _dbus_return_val_if_error_is_set (error, 0);
1333 
1337  "ReleaseName");
1338 
1339  if (message == NULL)
1340  {
1341  _DBUS_SET_OOM (error);
1342  return -1;
1343  }
1344 
1345  if (!dbus_message_append_args (message,
1346  DBUS_TYPE_STRING, &name,
1348  {
1349  dbus_message_unref (message);
1350  _DBUS_SET_OOM (error);
1351  return -1;
1352  }
1353 
1354  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1355  error);
1356 
1357  dbus_message_unref (message);
1358 
1359  if (reply == NULL)
1360  {
1361  _DBUS_ASSERT_ERROR_IS_SET (error);
1362  return -1;
1363  }
1364 
1365  if (dbus_set_error_from_message (error, reply))
1366  {
1367  _DBUS_ASSERT_ERROR_IS_SET (error);
1368  dbus_message_unref (reply);
1369  return -1;
1370  }
1371 
1372  if (!dbus_message_get_args (reply, error,
1373  DBUS_TYPE_UINT32, &result,
1375  {
1376  _DBUS_ASSERT_ERROR_IS_SET (error);
1377  dbus_message_unref (reply);
1378  return -1;
1379  }
1380 
1381  dbus_message_unref (reply);
1382 
1383  return result;
1384 }
1385 
1405  const char *name,
1406  DBusError *error)
1407 {
1408  DBusMessage *message, *reply;
1409  dbus_bool_t exists;
1410 
1411  _dbus_return_val_if_fail (connection != NULL, FALSE);
1412  _dbus_return_val_if_fail (name != NULL, FALSE);
1413  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1414  _dbus_return_val_if_error_is_set (error, FALSE);
1415 
1419  "NameHasOwner");
1420  if (message == NULL)
1421  {
1422  _DBUS_SET_OOM (error);
1423  return FALSE;
1424  }
1425 
1426  if (!dbus_message_append_args (message,
1427  DBUS_TYPE_STRING, &name,
1429  {
1430  dbus_message_unref (message);
1431  _DBUS_SET_OOM (error);
1432  return FALSE;
1433  }
1434 
1435  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1436  dbus_message_unref (message);
1437 
1438  if (reply == NULL)
1439  {
1440  _DBUS_ASSERT_ERROR_IS_SET (error);
1441  return FALSE;
1442  }
1443 
1444  if (!dbus_message_get_args (reply, error,
1445  DBUS_TYPE_BOOLEAN, &exists,
1447  {
1448  _DBUS_ASSERT_ERROR_IS_SET (error);
1449  dbus_message_unref (reply);
1450  return FALSE;
1451  }
1452 
1453  dbus_message_unref (reply);
1454  return exists;
1455 }
1456 
1481  const char *name,
1482  dbus_uint32_t flags,
1483  dbus_uint32_t *result,
1484  DBusError *error)
1485 {
1486  DBusMessage *msg;
1487  DBusMessage *reply;
1488 
1489  _dbus_return_val_if_fail (connection != NULL, FALSE);
1490  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1491 
1495  "StartServiceByName");
1496 
1497  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1499  {
1500  dbus_message_unref (msg);
1501  _DBUS_SET_OOM (error);
1502  return FALSE;
1503  }
1504 
1505  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1506  -1, error);
1507  dbus_message_unref (msg);
1508 
1509  if (reply == NULL)
1510  {
1511  _DBUS_ASSERT_ERROR_IS_SET (error);
1512  return FALSE;
1513  }
1514 
1515  if (dbus_set_error_from_message (error, reply))
1516  {
1517  _DBUS_ASSERT_ERROR_IS_SET (error);
1518  dbus_message_unref (reply);
1519  return FALSE;
1520  }
1521 
1522  if (result != NULL &&
1523  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1524  result, DBUS_TYPE_INVALID))
1525  {
1526  _DBUS_ASSERT_ERROR_IS_SET (error);
1527  dbus_message_unref (reply);
1528  return FALSE;
1529  }
1530 
1531  dbus_message_unref (reply);
1532  return TRUE;
1533 }
1534 
1535 static void
1536 send_no_return_values (DBusConnection *connection,
1537  DBusMessage *msg,
1538  DBusError *error)
1539 {
1540  if (error)
1541  {
1542  /* Block to check success codepath */
1543  DBusMessage *reply;
1544 
1545  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1546  -1, error);
1547 
1548  if (reply == NULL)
1549  _DBUS_ASSERT_ERROR_IS_SET (error);
1550  else
1551  dbus_message_unref (reply);
1552  }
1553  else
1554  {
1555  /* Silently-fail nonblocking codepath */
1557  dbus_connection_send (connection, msg, NULL);
1558  }
1559 }
1560 
1649 void
1651  const char *rule,
1652  DBusError *error)
1653 {
1654  DBusMessage *msg;
1655 
1656  _dbus_return_if_fail (rule != NULL);
1657 
1661  "AddMatch");
1662 
1663  if (msg == NULL)
1664  {
1665  _DBUS_SET_OOM (error);
1666  return;
1667  }
1668 
1669  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1671  {
1672  dbus_message_unref (msg);
1673  _DBUS_SET_OOM (error);
1674  return;
1675  }
1676 
1677  send_no_return_values (connection, msg, error);
1678 
1679  dbus_message_unref (msg);
1680 }
1681 
1699 void
1701  const char *rule,
1702  DBusError *error)
1703 {
1704  DBusMessage *msg;
1705 
1706  _dbus_return_if_fail (rule != NULL);
1707 
1711  "RemoveMatch");
1712 
1713  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1715  {
1716  dbus_message_unref (msg);
1717  _DBUS_SET_OOM (error);
1718  return;
1719  }
1720 
1721  send_no_return_values (connection, msg, error);
1722 
1723  dbus_message_unref (msg);
1724 }
1725 
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:1322
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:89
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:76
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:107
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:181
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:1236
#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:78
The systemwide bus.
Definition: dbus-shared.h:59
dbus_bool_t _dbus_setenv(const char *varname, const char *value)
Wrapper for setenv().
Definition: dbus-sysdeps.c:110
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:696
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:899
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
char * unique_name
Unique name of this connection.
Definition: dbus-bus.c:79
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:1700
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:401
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
#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;.
dbus_bool_t dbus_bus_register(DBusConnection *connection, DBusError *error)
Registers a connection with the bus.
Definition: dbus-bus.c:784
#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:1480
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
#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:989
#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:81
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:1650
#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:944
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.
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:1072
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:619
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:728
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:1404
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *interface, const char *method)
Constructs a new message to invoke a method on a remote object.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329