D-Bus  1.13.7
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.");
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", error.message);
172  else
173  _dbus_warn ("Dynamic session lookup supported but failed silently");
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 DBusConnection *
416 internal_bus_get (DBusBusType type,
417  dbus_bool_t private,
418  DBusError *error)
419 {
420  const char *address;
421  DBusConnection *connection;
422  BusData *bd;
423  DBusBusType address_type;
424 
425  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
426  _dbus_return_val_if_error_is_set (error, NULL);
427 
428  connection = NULL;
429 
430  if (!_DBUS_LOCK (bus))
431  {
432  _DBUS_SET_OOM (error);
433  /* do not "goto out", that would try to unlock */
434  return NULL;
435  }
436 
437  if (!init_connections_unlocked ())
438  {
439  _DBUS_SET_OOM (error);
440  goto out;
441  }
442 
443  /* We want to use the activation address even if the
444  * activating bus is the session or system bus,
445  * per the spec.
446  */
447  address_type = type;
448 
449  /* Use the real type of the activation bus for getting its
450  * connection, but only if the real type's address is available. (If
451  * the activating bus isn't a well-known bus then
452  * activation_bus_type == DBUS_BUS_STARTER)
453  */
454  if (type == DBUS_BUS_STARTER &&
455  bus_connection_addresses[activation_bus_type] != NULL)
456  type = activation_bus_type;
457 
458  if (!private && bus_connections[type] != NULL)
459  {
460  connection = bus_connections[type];
461  dbus_connection_ref (connection);
462  goto out;
463  }
464 
465  address = bus_connection_addresses[address_type];
466  if (address == NULL)
467  {
469  "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
470  goto out;
471  }
472 
473  if (private)
474  connection = dbus_connection_open_private (address, error);
475  else
476  connection = dbus_connection_open (address, error);
477 
478  if (!connection)
479  {
480  goto out;
481  }
482 
483  if (!dbus_bus_register (connection, error))
484  {
486  dbus_connection_unref (connection);
487  connection = NULL;
488  goto out;
489  }
490 
491  if (!private)
492  {
493  /* store a weak ref to the connection (dbus-connection.c is
494  * supposed to have a strong ref that it drops on disconnect,
495  * since this is a shared connection)
496  */
497  bus_connections[type] = connection;
498  }
499 
500  /* By default we're bound to the lifecycle of
501  * the message bus.
502  */
504  TRUE);
505 
506  if (!_DBUS_LOCK (bus_datas))
507  _dbus_assert_not_reached ("global locks were initialized already");
508 
509  bd = ensure_bus_data (connection);
510  _dbus_assert (bd != NULL); /* it should have been created on
511  register, so OOM not possible */
512  bd->is_well_known = TRUE;
513  _DBUS_UNLOCK (bus_datas);
514 
515 out:
516  /* Return a reference to the caller, or NULL with error set. */
517  if (connection == NULL)
518  _DBUS_ASSERT_ERROR_IS_SET (error);
519 
520  _DBUS_UNLOCK (bus);
521  return connection;
522 }
523 
524  /* end of implementation details docs */
526 
559  DBusError *error)
560 {
561  return internal_bus_get (type, FALSE, error);
562 }
563 
591  DBusError *error)
592 {
593  return internal_bus_get (type, TRUE, error);
594 }
595 
647  DBusError *error)
648 {
649  DBusMessage *message, *reply;
650  char *name;
651  BusData *bd;
652  dbus_bool_t retval;
653 
654  _dbus_return_val_if_fail (connection != NULL, FALSE);
655  _dbus_return_val_if_error_is_set (error, FALSE);
656 
657  retval = FALSE;
658  message = NULL;
659  reply = NULL;
660 
661  if (!_DBUS_LOCK (bus_datas))
662  {
663  _DBUS_SET_OOM (error);
664  /* do not "goto out", that would try to unlock */
665  return FALSE;
666  }
667 
668  bd = ensure_bus_data (connection);
669  if (bd == NULL)
670  {
671  _DBUS_SET_OOM (error);
672  goto out;
673  }
674 
675  if (bd->unique_name != NULL)
676  {
677  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
678  bd->unique_name);
679  /* Success! */
680  retval = TRUE;
681  goto out;
682  }
683 
687  "Hello");
688 
689  if (!message)
690  {
691  _DBUS_SET_OOM (error);
692  goto out;
693  }
694 
695  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
696 
697  if (reply == NULL)
698  goto out;
699  else if (dbus_set_error_from_message (error, reply))
700  goto out;
701  else if (!dbus_message_get_args (reply, error,
702  DBUS_TYPE_STRING, &name,
704  goto out;
705 
706  bd->unique_name = _dbus_strdup (name);
707  if (bd->unique_name == NULL)
708  {
709  _DBUS_SET_OOM (error);
710  goto out;
711  }
712 
713  retval = TRUE;
714 
715  out:
716  _DBUS_UNLOCK (bus_datas);
717 
718  if (message)
719  dbus_message_unref (message);
720 
721  if (reply)
722  dbus_message_unref (reply);
723 
724  if (!retval)
725  _DBUS_ASSERT_ERROR_IS_SET (error);
726 
727  return retval;
728 }
729 
730 
767  const char *unique_name)
768 {
769  BusData *bd;
770  dbus_bool_t success = FALSE;
771 
772  _dbus_return_val_if_fail (connection != NULL, FALSE);
773  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
774 
775  if (!_DBUS_LOCK (bus_datas))
776  {
777  /* do not "goto out", that would try to unlock */
778  return FALSE;
779  }
780 
781  bd = ensure_bus_data (connection);
782  if (bd == NULL)
783  goto out;
784 
785  _dbus_assert (bd->unique_name == NULL);
786 
787  bd->unique_name = _dbus_strdup (unique_name);
788  success = bd->unique_name != NULL;
789 
790 out:
791  _DBUS_UNLOCK (bus_datas);
792 
793  return success;
794 }
795 
814 const char*
816 {
817  BusData *bd;
818  const char *unique_name = NULL;
819 
820  _dbus_return_val_if_fail (connection != NULL, NULL);
821 
822  if (!_DBUS_LOCK (bus_datas))
823  {
824  /* We'd have initialized locks when we gave it its unique name, if it
825  * had one. Don't "goto out", that would try to unlock. */
826  return NULL;
827  }
828 
829  bd = ensure_bus_data (connection);
830  if (bd == NULL)
831  goto out;
832 
833  unique_name = bd->unique_name;
834 
835 out:
836  _DBUS_UNLOCK (bus_datas);
837 
838  return unique_name;
839 }
840 
864 unsigned long
866  const char *name,
867  DBusError *error)
868 {
869  DBusMessage *message, *reply;
870  dbus_uint32_t uid;
871 
872  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
873  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
874  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
875  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
876 
880  "GetConnectionUnixUser");
881 
882  if (message == NULL)
883  {
884  _DBUS_SET_OOM (error);
885  return DBUS_UID_UNSET;
886  }
887 
888  if (!dbus_message_append_args (message,
889  DBUS_TYPE_STRING, &name,
891  {
892  dbus_message_unref (message);
893  _DBUS_SET_OOM (error);
894  return DBUS_UID_UNSET;
895  }
896 
897  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
898  error);
899 
900  dbus_message_unref (message);
901 
902  if (reply == NULL)
903  {
904  _DBUS_ASSERT_ERROR_IS_SET (error);
905  return DBUS_UID_UNSET;
906  }
907 
908  if (dbus_set_error_from_message (error, reply))
909  {
910  _DBUS_ASSERT_ERROR_IS_SET (error);
911  dbus_message_unref (reply);
912  return DBUS_UID_UNSET;
913  }
914 
915  if (!dbus_message_get_args (reply, error,
916  DBUS_TYPE_UINT32, &uid,
918  {
919  _DBUS_ASSERT_ERROR_IS_SET (error);
920  dbus_message_unref (reply);
921  return DBUS_UID_UNSET;
922  }
923 
924  dbus_message_unref (reply);
925 
926  return (unsigned long) uid;
927 }
928 
947 char*
949  DBusError *error)
950 {
951  DBusMessage *message, *reply;
952  char *id;
953  const char *v_STRING;
954 
955  _dbus_return_val_if_fail (connection != NULL, NULL);
956  _dbus_return_val_if_error_is_set (error, NULL);
957 
961  "GetId");
962 
963  if (message == NULL)
964  {
965  _DBUS_SET_OOM (error);
966  return NULL;
967  }
968 
969  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
970  error);
971 
972  dbus_message_unref (message);
973 
974  if (reply == NULL)
975  {
976  _DBUS_ASSERT_ERROR_IS_SET (error);
977  return NULL;
978  }
979 
980  if (dbus_set_error_from_message (error, reply))
981  {
982  _DBUS_ASSERT_ERROR_IS_SET (error);
983  dbus_message_unref (reply);
984  return NULL;
985  }
986 
987  v_STRING = NULL;
988  if (!dbus_message_get_args (reply, error,
989  DBUS_TYPE_STRING, &v_STRING,
991  {
992  _DBUS_ASSERT_ERROR_IS_SET (error);
993  dbus_message_unref (reply);
994  return NULL;
995  }
996 
997  id = _dbus_strdup (v_STRING); /* may be NULL */
998 
999  dbus_message_unref (reply);
1000 
1001  if (id == NULL)
1002  _DBUS_SET_OOM (error);
1003 
1004  /* FIXME it might be nice to cache the ID locally */
1005 
1006  return id;
1007 }
1008 
1111 int
1113  const char *name,
1114  unsigned int flags,
1115  DBusError *error)
1116 {
1117  DBusMessage *message, *reply;
1118  dbus_uint32_t result;
1119 
1120  _dbus_return_val_if_fail (connection != NULL, 0);
1121  _dbus_return_val_if_fail (name != NULL, 0);
1122  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1123  _dbus_return_val_if_error_is_set (error, 0);
1124 
1128  "RequestName");
1129 
1130  if (message == NULL)
1131  {
1132  _DBUS_SET_OOM (error);
1133  return -1;
1134  }
1135 
1136  if (!dbus_message_append_args (message,
1137  DBUS_TYPE_STRING, &name,
1138  DBUS_TYPE_UINT32, &flags,
1140  {
1141  dbus_message_unref (message);
1142  _DBUS_SET_OOM (error);
1143  return -1;
1144  }
1145 
1146  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1147  error);
1148 
1149  dbus_message_unref (message);
1150 
1151  if (reply == NULL)
1152  {
1153  _DBUS_ASSERT_ERROR_IS_SET (error);
1154  return -1;
1155  }
1156 
1157  if (dbus_set_error_from_message (error, reply))
1158  {
1159  _DBUS_ASSERT_ERROR_IS_SET (error);
1160  dbus_message_unref (reply);
1161  return -1;
1162  }
1163 
1164  if (!dbus_message_get_args (reply, error,
1165  DBUS_TYPE_UINT32, &result,
1167  {
1168  _DBUS_ASSERT_ERROR_IS_SET (error);
1169  dbus_message_unref (reply);
1170  return -1;
1171  }
1172 
1173  dbus_message_unref (reply);
1174 
1175  return result;
1176 }
1177 
1178 
1197 int
1199  const char *name,
1200  DBusError *error)
1201 {
1202  DBusMessage *message, *reply;
1203  dbus_uint32_t result;
1204 
1205  _dbus_return_val_if_fail (connection != NULL, 0);
1206  _dbus_return_val_if_fail (name != NULL, 0);
1207  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1208  _dbus_return_val_if_error_is_set (error, 0);
1209 
1213  "ReleaseName");
1214 
1215  if (message == NULL)
1216  {
1217  _DBUS_SET_OOM (error);
1218  return -1;
1219  }
1220 
1221  if (!dbus_message_append_args (message,
1222  DBUS_TYPE_STRING, &name,
1224  {
1225  dbus_message_unref (message);
1226  _DBUS_SET_OOM (error);
1227  return -1;
1228  }
1229 
1230  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1231  error);
1232 
1233  dbus_message_unref (message);
1234 
1235  if (reply == NULL)
1236  {
1237  _DBUS_ASSERT_ERROR_IS_SET (error);
1238  return -1;
1239  }
1240 
1241  if (dbus_set_error_from_message (error, reply))
1242  {
1243  _DBUS_ASSERT_ERROR_IS_SET (error);
1244  dbus_message_unref (reply);
1245  return -1;
1246  }
1247 
1248  if (!dbus_message_get_args (reply, error,
1249  DBUS_TYPE_UINT32, &result,
1251  {
1252  _DBUS_ASSERT_ERROR_IS_SET (error);
1253  dbus_message_unref (reply);
1254  return -1;
1255  }
1256 
1257  dbus_message_unref (reply);
1258 
1259  return result;
1260 }
1261 
1281  const char *name,
1282  DBusError *error)
1283 {
1284  DBusMessage *message, *reply;
1285  dbus_bool_t exists;
1286 
1287  _dbus_return_val_if_fail (connection != NULL, FALSE);
1288  _dbus_return_val_if_fail (name != NULL, FALSE);
1289  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1290  _dbus_return_val_if_error_is_set (error, FALSE);
1291 
1295  "NameHasOwner");
1296  if (message == NULL)
1297  {
1298  _DBUS_SET_OOM (error);
1299  return FALSE;
1300  }
1301 
1302  if (!dbus_message_append_args (message,
1303  DBUS_TYPE_STRING, &name,
1305  {
1306  dbus_message_unref (message);
1307  _DBUS_SET_OOM (error);
1308  return FALSE;
1309  }
1310 
1311  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1312  dbus_message_unref (message);
1313 
1314  if (reply == NULL)
1315  {
1316  _DBUS_ASSERT_ERROR_IS_SET (error);
1317  return FALSE;
1318  }
1319 
1320  if (!dbus_message_get_args (reply, error,
1321  DBUS_TYPE_BOOLEAN, &exists,
1323  {
1324  _DBUS_ASSERT_ERROR_IS_SET (error);
1325  dbus_message_unref (reply);
1326  return FALSE;
1327  }
1328 
1329  dbus_message_unref (reply);
1330  return exists;
1331 }
1332 
1357  const char *name,
1358  dbus_uint32_t flags,
1359  dbus_uint32_t *result,
1360  DBusError *error)
1361 {
1362  DBusMessage *msg;
1363  DBusMessage *reply;
1364 
1365  _dbus_return_val_if_fail (connection != NULL, FALSE);
1366  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1367 
1371  "StartServiceByName");
1372 
1373  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1375  {
1376  dbus_message_unref (msg);
1377  _DBUS_SET_OOM (error);
1378  return FALSE;
1379  }
1380 
1381  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1382  -1, error);
1383  dbus_message_unref (msg);
1384 
1385  if (reply == NULL)
1386  {
1387  _DBUS_ASSERT_ERROR_IS_SET (error);
1388  return FALSE;
1389  }
1390 
1391  if (dbus_set_error_from_message (error, reply))
1392  {
1393  _DBUS_ASSERT_ERROR_IS_SET (error);
1394  dbus_message_unref (reply);
1395  return FALSE;
1396  }
1397 
1398  if (result != NULL &&
1399  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1400  result, DBUS_TYPE_INVALID))
1401  {
1402  _DBUS_ASSERT_ERROR_IS_SET (error);
1403  dbus_message_unref (reply);
1404  return FALSE;
1405  }
1406 
1407  dbus_message_unref (reply);
1408  return TRUE;
1409 }
1410 
1411 static void
1412 send_no_return_values (DBusConnection *connection,
1413  DBusMessage *msg,
1414  DBusError *error)
1415 {
1416  if (error)
1417  {
1418  /* Block to check success codepath */
1419  DBusMessage *reply;
1420 
1421  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1422  -1, error);
1423 
1424  if (reply == NULL)
1425  _DBUS_ASSERT_ERROR_IS_SET (error);
1426  else
1427  dbus_message_unref (reply);
1428  }
1429  else
1430  {
1431  /* Silently-fail nonblocking codepath */
1433  dbus_connection_send (connection, msg, NULL);
1434  }
1435 }
1436 
1525 void
1527  const char *rule,
1528  DBusError *error)
1529 {
1530  DBusMessage *msg;
1531 
1532  _dbus_return_if_fail (rule != NULL);
1533 
1537  "AddMatch");
1538 
1539  if (msg == NULL)
1540  {
1541  _DBUS_SET_OOM (error);
1542  return;
1543  }
1544 
1545  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1547  {
1548  dbus_message_unref (msg);
1549  _DBUS_SET_OOM (error);
1550  return;
1551  }
1552 
1553  send_no_return_values (connection, msg, error);
1554 
1555  dbus_message_unref (msg);
1556 }
1557 
1575 void
1577  const char *rule,
1578  DBusError *error)
1579 {
1580  DBusMessage *msg;
1581 
1582  _dbus_return_if_fail (rule != NULL);
1583 
1587  "RemoveMatch");
1588 
1589  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1591  {
1592  dbus_message_unref (msg);
1593  _DBUS_SET_OOM (error);
1594  return;
1595  }
1596 
1597  send_no_return_values (connection, msg, error);
1598 
1599  dbus_message_unref (msg);
1600 }
1601 
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:703
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:1198
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 "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: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:141
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:1112
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
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:558
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:766
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 "by value" (the most recently-added identical rule gets removed...
Definition: dbus-bus.c:1576
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(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
#define TRUE
Expands to "1".
#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:646
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - 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:1356
#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:865
#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:1526
#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:815
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:812
#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:948
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:658
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
char * _dbus_strdup(const char *str)
Duplicates a string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
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:590
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:1280
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329