D-Bus  1.6.12
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 
98 static void
99 addresses_shutdown_func (void *data)
100 {
101  int i;
102 
103  i = 0;
104  while (i < N_BUS_TYPES)
105  {
106  if (bus_connections[i] != NULL)
107  _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");
108 
109  dbus_free (bus_connection_addresses[i]);
110  bus_connection_addresses[i] = NULL;
111  ++i;
112  }
113 
114  activation_bus_type = DBUS_BUS_STARTER;
115 
116  initialized = FALSE;
117 }
118 
119 static dbus_bool_t
120 get_from_env (char **connection_p,
121  const char *env_var)
122 {
123  const char *s;
124 
125  _dbus_assert (*connection_p == NULL);
126 
127  s = _dbus_getenv (env_var);
128  if (s == NULL || *s == '\0')
129  return TRUE; /* successfully didn't use the env var */
130  else
131  {
132  *connection_p = _dbus_strdup (s);
133  return *connection_p != NULL;
134  }
135 }
136 
137 static dbus_bool_t
138 init_session_address (void)
139 {
140  dbus_bool_t retval;
141 
142  retval = FALSE;
143 
144  /* First, look in the environment. This is the normal case on
145  * freedesktop.org/Unix systems. */
146  get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
147  "DBUS_SESSION_BUS_ADDRESS");
148  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
149  {
150  dbus_bool_t supported;
151  DBusString addr;
152  DBusError error = DBUS_ERROR_INIT;
153 
154  if (!_dbus_string_init (&addr))
155  return FALSE;
156 
157  supported = FALSE;
158  /* So it's not in the environment - let's try a platform-specific method.
159  * On MacOS, this involves asking launchd. On Windows (not specified yet)
160  * we might do a COM lookup.
161  * Ignore errors - if we failed, fall back to autolaunch. */
162  retval = _dbus_lookup_session_address (&supported, &addr, &error);
163  if (supported && retval)
164  {
165  retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
166  }
167  else if (supported && !retval)
168  {
169  if (dbus_error_is_set(&error))
170  _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message);
171  else
172  _dbus_warn ("Dynamic session lookup supported but failed silently\n");
173  }
174  _dbus_string_free (&addr);
175  }
176  else
177  retval = TRUE;
178 
179  if (!retval)
180  return FALSE;
181 
182  /* The DBUS_SESSION_BUS_DEFAULT_ADDRESS should have really been named
183  * DBUS_SESSION_BUS_FALLBACK_ADDRESS.
184  */
185  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
186  bus_connection_addresses[DBUS_BUS_SESSION] =
187  _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
188  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
189  return FALSE;
190 
191  return TRUE;
192 }
193 
194 static dbus_bool_t
195 init_connections_unlocked (void)
196 {
197  if (!initialized)
198  {
199  const char *s;
200  int i;
201 
202  i = 0;
203  while (i < N_BUS_TYPES)
204  {
205  bus_connections[i] = NULL;
206  ++i;
207  }
208 
209  /* Don't init these twice, we may run this code twice if
210  * init_connections_unlocked() fails midway through.
211  * In practice, each block below should contain only one
212  * "return FALSE" or running through twice may not
213  * work right.
214  */
215 
216  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
217  {
218  _dbus_verbose ("Filling in system bus address...\n");
219 
220  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
221  "DBUS_SYSTEM_BUS_ADDRESS"))
222  return FALSE;
223  }
224 
225 
226  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
227  {
228  /* Use default system bus address if none set in environment */
229  bus_connection_addresses[DBUS_BUS_SYSTEM] =
230  _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
231 
232  if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
233  return FALSE;
234 
235  _dbus_verbose (" used default system bus \"%s\"\n",
236  bus_connection_addresses[DBUS_BUS_SYSTEM]);
237  }
238  else
239  _dbus_verbose (" used env var system bus \"%s\"\n",
240  bus_connection_addresses[DBUS_BUS_SYSTEM]);
241 
242  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
243  {
244  _dbus_verbose ("Filling in session bus address...\n");
245 
246  if (!init_session_address ())
247  return FALSE;
248 
249  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
250  bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
251  }
252 
253  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
254  {
255  _dbus_verbose ("Filling in activation bus address...\n");
256 
257  if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
258  "DBUS_STARTER_ADDRESS"))
259  return FALSE;
260 
261  _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
262  bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
263  }
264 
265 
266  if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
267  {
268  s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
269 
270  if (s != NULL)
271  {
272  _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
273 
274  if (strcmp (s, "system") == 0)
275  activation_bus_type = DBUS_BUS_SYSTEM;
276  else if (strcmp (s, "session") == 0)
277  activation_bus_type = DBUS_BUS_SESSION;
278  }
279  }
280  else
281  {
282  /* Default to the session bus instead if available */
283  if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
284  {
285  bus_connection_addresses[DBUS_BUS_STARTER] =
286  _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
287  if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
288  return FALSE;
289  }
290  }
291 
292  /* If we return FALSE we have to be sure that restarting
293  * the above code will work right
294  */
295 
296  if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
297  return FALSE;
298 
299  if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
300  return FALSE;
301 
302  if (!_dbus_register_shutdown_func (addresses_shutdown_func,
303  NULL))
304  return FALSE;
305 
306  initialized = TRUE;
307  }
308 
309  return initialized;
310 }
311 
312 static void
313 bus_data_free (void *data)
314 {
315  BusData *bd = data;
316 
317  if (bd->is_well_known)
318  {
319  int i;
320 
321  if (!_DBUS_LOCK (bus))
322  _dbus_assert_not_reached ("global locks should have been initialized "
323  "when we attached bus data");
324 
325  /* We may be stored in more than one slot */
326  /* This should now be impossible - these slots are supposed to
327  * be cleared on disconnect, so should not need to be cleared on
328  * finalize
329  */
330  i = 0;
331  while (i < N_BUS_TYPES)
332  {
333  if (bus_connections[i] == bd->connection)
334  bus_connections[i] = NULL;
335 
336  ++i;
337  }
338  _DBUS_UNLOCK (bus);
339  }
340 
341  dbus_free (bd->unique_name);
342  dbus_free (bd);
343 
344  dbus_connection_free_data_slot (&bus_data_slot);
345 }
346 
347 static BusData*
348 ensure_bus_data (DBusConnection *connection)
349 {
350  BusData *bd;
351 
352  if (!dbus_connection_allocate_data_slot (&bus_data_slot))
353  return NULL;
354 
355  bd = dbus_connection_get_data (connection, bus_data_slot);
356  if (bd == NULL)
357  {
358  bd = dbus_new0 (BusData, 1);
359  if (bd == NULL)
360  {
361  dbus_connection_free_data_slot (&bus_data_slot);
362  return NULL;
363  }
364 
365  bd->connection = connection;
366 
367  if (!dbus_connection_set_data (connection, bus_data_slot, bd,
368  bus_data_free))
369  {
370  dbus_free (bd);
371  dbus_connection_free_data_slot (&bus_data_slot);
372  return NULL;
373  }
374 
375  /* Data slot refcount now held by the BusData */
376  }
377  else
378  {
379  dbus_connection_free_data_slot (&bus_data_slot);
380  }
381 
382  return bd;
383 }
384 
391 void
393 {
394  int i;
395 
396  if (!_DBUS_LOCK (bus))
397  {
398  /* If it was in bus_connections, we would have initialized global locks
399  * when we added it. So, it can't be. */
400  return;
401  }
402 
403  /* We are expecting to have the connection saved in only one of these
404  * slots, but someone could in a pathological case set system and session
405  * bus to the same bus or something. Or set one of them to the starter
406  * bus without setting the starter bus type in the env variable.
407  * So we don't break the loop as soon as we find a match.
408  */
409  for (i = 0; i < N_BUS_TYPES; ++i)
410  {
411  if (bus_connections[i] == connection)
412  {
413  bus_connections[i] = NULL;
414  }
415  }
416 
417  _DBUS_UNLOCK (bus);
418 }
419 
420 static DBusConnection *
421 internal_bus_get (DBusBusType type,
422  dbus_bool_t private,
423  DBusError *error)
424 {
425  const char *address;
426  DBusConnection *connection;
427  BusData *bd;
428  DBusBusType address_type;
429 
430  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
431  _dbus_return_val_if_error_is_set (error, NULL);
432 
433  connection = NULL;
434 
435  if (!_DBUS_LOCK (bus))
436  {
437  _DBUS_SET_OOM (error);
438  /* do not "goto out", that would try to unlock */
439  return NULL;
440  }
441 
442  if (!init_connections_unlocked ())
443  {
444  _DBUS_SET_OOM (error);
445  goto out;
446  }
447 
448  /* We want to use the activation address even if the
449  * activating bus is the session or system bus,
450  * per the spec.
451  */
452  address_type = type;
453 
454  /* Use the real type of the activation bus for getting its
455  * connection, but only if the real type's address is available. (If
456  * the activating bus isn't a well-known bus then
457  * activation_bus_type == DBUS_BUS_STARTER)
458  */
459  if (type == DBUS_BUS_STARTER &&
460  bus_connection_addresses[activation_bus_type] != NULL)
461  type = activation_bus_type;
462 
463  if (!private && bus_connections[type] != NULL)
464  {
465  connection = bus_connections[type];
466  dbus_connection_ref (connection);
467  goto out;
468  }
469 
470  address = bus_connection_addresses[address_type];
471  if (address == NULL)
472  {
474  "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
475  goto out;
476  }
477 
478  if (private)
479  connection = dbus_connection_open_private (address, error);
480  else
481  connection = dbus_connection_open (address, error);
482 
483  if (!connection)
484  {
485  goto out;
486  }
487 
488  if (!dbus_bus_register (connection, error))
489  {
491  dbus_connection_unref (connection);
492  connection = NULL;
493  goto out;
494  }
495 
496  if (!private)
497  {
498  /* store a weak ref to the connection (dbus-connection.c is
499  * supposed to have a strong ref that it drops on disconnect,
500  * since this is a shared connection)
501  */
502  bus_connections[type] = connection;
503  }
504 
505  /* By default we're bound to the lifecycle of
506  * the message bus.
507  */
509  TRUE);
510 
511  if (!_DBUS_LOCK (bus_datas))
512  _dbus_assert_not_reached ("global locks were initialized already");
513 
514  bd = ensure_bus_data (connection);
515  _dbus_assert (bd != NULL); /* it should have been created on
516  register, so OOM not possible */
517  bd->is_well_known = TRUE;
518  _DBUS_UNLOCK (bus_datas);
519 
520 out:
521  /* Return a reference to the caller, or NULL with error set. */
522  if (connection == NULL)
523  _DBUS_ASSERT_ERROR_IS_SET (error);
524 
525  _DBUS_UNLOCK (bus);
526  return connection;
527 }
528 
529  /* end of implementation details docs */
531 
564  DBusError *error)
565 {
566  return internal_bus_get (type, FALSE, error);
567 }
568 
596  DBusError *error)
597 {
598  return internal_bus_get (type, TRUE, error);
599 }
600 
652  DBusError *error)
653 {
654  DBusMessage *message, *reply;
655  char *name;
656  BusData *bd;
657  dbus_bool_t retval;
658 
659  _dbus_return_val_if_fail (connection != NULL, FALSE);
660  _dbus_return_val_if_error_is_set (error, FALSE);
661 
662  retval = FALSE;
663  message = NULL;
664  reply = NULL;
665 
666  if (!_DBUS_LOCK (bus_datas))
667  {
668  _DBUS_SET_OOM (error);
669  /* do not "goto out", that would try to unlock */
670  return FALSE;
671  }
672 
673  bd = ensure_bus_data (connection);
674  if (bd == NULL)
675  {
676  _DBUS_SET_OOM (error);
677  goto out;
678  }
679 
680  if (bd->unique_name != NULL)
681  {
682  _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
683  bd->unique_name);
684  /* Success! */
685  retval = TRUE;
686  goto out;
687  }
688 
692  "Hello");
693 
694  if (!message)
695  {
696  _DBUS_SET_OOM (error);
697  goto out;
698  }
699 
700  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
701 
702  if (reply == NULL)
703  goto out;
704  else if (dbus_set_error_from_message (error, reply))
705  goto out;
706  else if (!dbus_message_get_args (reply, error,
707  DBUS_TYPE_STRING, &name,
709  goto out;
710 
711  bd->unique_name = _dbus_strdup (name);
712  if (bd->unique_name == NULL)
713  {
714  _DBUS_SET_OOM (error);
715  goto out;
716  }
717 
718  retval = TRUE;
719 
720  out:
721  _DBUS_UNLOCK (bus_datas);
722 
723  if (message)
724  dbus_message_unref (message);
725 
726  if (reply)
727  dbus_message_unref (reply);
728 
729  if (!retval)
730  _DBUS_ASSERT_ERROR_IS_SET (error);
731 
732  return retval;
733 }
734 
735 
772  const char *unique_name)
773 {
774  BusData *bd;
775  dbus_bool_t success = FALSE;
776 
777  _dbus_return_val_if_fail (connection != NULL, FALSE);
778  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
779 
780  if (!_DBUS_LOCK (bus_datas))
781  {
782  /* do not "goto out", that would try to unlock */
783  return FALSE;
784  }
785 
786  bd = ensure_bus_data (connection);
787  if (bd == NULL)
788  goto out;
789 
790  _dbus_assert (bd->unique_name == NULL);
791 
792  bd->unique_name = _dbus_strdup (unique_name);
793  success = bd->unique_name != NULL;
794 
795 out:
796  _DBUS_UNLOCK (bus_datas);
797 
798  return success;
799 }
800 
819 const char*
821 {
822  BusData *bd;
823  const char *unique_name = NULL;
824 
825  _dbus_return_val_if_fail (connection != NULL, NULL);
826 
827  if (!_DBUS_LOCK (bus_datas))
828  {
829  /* We'd have initialized locks when we gave it its unique name, if it
830  * had one. Don't "goto out", that would try to unlock. */
831  return NULL;
832  }
833 
834  bd = ensure_bus_data (connection);
835  if (bd == NULL)
836  goto out;
837 
838  unique_name = bd->unique_name;
839 
840 out:
841  _DBUS_UNLOCK (bus_datas);
842 
843  return unique_name;
844 }
845 
869 unsigned long
871  const char *name,
872  DBusError *error)
873 {
874  DBusMessage *message, *reply;
875  dbus_uint32_t uid;
876 
877  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
878  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
879  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
880  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
881 
885  "GetConnectionUnixUser");
886 
887  if (message == NULL)
888  {
889  _DBUS_SET_OOM (error);
890  return DBUS_UID_UNSET;
891  }
892 
893  if (!dbus_message_append_args (message,
894  DBUS_TYPE_STRING, &name,
896  {
897  dbus_message_unref (message);
898  _DBUS_SET_OOM (error);
899  return DBUS_UID_UNSET;
900  }
901 
902  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
903  error);
904 
905  dbus_message_unref (message);
906 
907  if (reply == NULL)
908  {
909  _DBUS_ASSERT_ERROR_IS_SET (error);
910  return DBUS_UID_UNSET;
911  }
912 
913  if (dbus_set_error_from_message (error, reply))
914  {
915  _DBUS_ASSERT_ERROR_IS_SET (error);
916  dbus_message_unref (reply);
917  return DBUS_UID_UNSET;
918  }
919 
920  if (!dbus_message_get_args (reply, error,
921  DBUS_TYPE_UINT32, &uid,
923  {
924  _DBUS_ASSERT_ERROR_IS_SET (error);
925  dbus_message_unref (reply);
926  return DBUS_UID_UNSET;
927  }
928 
929  dbus_message_unref (reply);
930 
931  return (unsigned long) uid;
932 }
933 
952 char*
954  DBusError *error)
955 {
956  DBusMessage *message, *reply;
957  char *id;
958  const char *v_STRING;
959 
960  _dbus_return_val_if_fail (connection != NULL, NULL);
961  _dbus_return_val_if_error_is_set (error, NULL);
962 
966  "GetId");
967 
968  if (message == NULL)
969  {
970  _DBUS_SET_OOM (error);
971  return NULL;
972  }
973 
974  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
975  error);
976 
977  dbus_message_unref (message);
978 
979  if (reply == NULL)
980  {
981  _DBUS_ASSERT_ERROR_IS_SET (error);
982  return NULL;
983  }
984 
985  if (dbus_set_error_from_message (error, reply))
986  {
987  _DBUS_ASSERT_ERROR_IS_SET (error);
988  dbus_message_unref (reply);
989  return NULL;
990  }
991 
992  v_STRING = NULL;
993  if (!dbus_message_get_args (reply, error,
994  DBUS_TYPE_STRING, &v_STRING,
996  {
997  _DBUS_ASSERT_ERROR_IS_SET (error);
998  dbus_message_unref (reply);
999  return NULL;
1000  }
1001 
1002  id = _dbus_strdup (v_STRING); /* may be NULL */
1003 
1004  dbus_message_unref (reply);
1005 
1006  if (id == NULL)
1007  _DBUS_SET_OOM (error);
1008 
1009  /* FIXME it might be nice to cache the ID locally */
1010 
1011  return id;
1012 }
1013 
1116 int
1118  const char *name,
1119  unsigned int flags,
1120  DBusError *error)
1121 {
1122  DBusMessage *message, *reply;
1123  dbus_uint32_t result;
1124 
1125  _dbus_return_val_if_fail (connection != NULL, 0);
1126  _dbus_return_val_if_fail (name != NULL, 0);
1127  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1128  _dbus_return_val_if_error_is_set (error, 0);
1129 
1133  "RequestName");
1134 
1135  if (message == NULL)
1136  {
1137  _DBUS_SET_OOM (error);
1138  return -1;
1139  }
1140 
1141  if (!dbus_message_append_args (message,
1142  DBUS_TYPE_STRING, &name,
1143  DBUS_TYPE_UINT32, &flags,
1145  {
1146  dbus_message_unref (message);
1147  _DBUS_SET_OOM (error);
1148  return -1;
1149  }
1150 
1151  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1152  error);
1153 
1154  dbus_message_unref (message);
1155 
1156  if (reply == NULL)
1157  {
1158  _DBUS_ASSERT_ERROR_IS_SET (error);
1159  return -1;
1160  }
1161 
1162  if (dbus_set_error_from_message (error, reply))
1163  {
1164  _DBUS_ASSERT_ERROR_IS_SET (error);
1165  dbus_message_unref (reply);
1166  return -1;
1167  }
1168 
1169  if (!dbus_message_get_args (reply, error,
1170  DBUS_TYPE_UINT32, &result,
1172  {
1173  _DBUS_ASSERT_ERROR_IS_SET (error);
1174  dbus_message_unref (reply);
1175  return -1;
1176  }
1177 
1178  dbus_message_unref (reply);
1179 
1180  return result;
1181 }
1182 
1183 
1202 int
1204  const char *name,
1205  DBusError *error)
1206 {
1207  DBusMessage *message, *reply;
1208  dbus_uint32_t result;
1209 
1210  _dbus_return_val_if_fail (connection != NULL, 0);
1211  _dbus_return_val_if_fail (name != NULL, 0);
1212  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1213  _dbus_return_val_if_error_is_set (error, 0);
1214 
1218  "ReleaseName");
1219 
1220  if (message == NULL)
1221  {
1222  _DBUS_SET_OOM (error);
1223  return -1;
1224  }
1225 
1226  if (!dbus_message_append_args (message,
1227  DBUS_TYPE_STRING, &name,
1229  {
1230  dbus_message_unref (message);
1231  _DBUS_SET_OOM (error);
1232  return -1;
1233  }
1234 
1235  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1236  error);
1237 
1238  dbus_message_unref (message);
1239 
1240  if (reply == NULL)
1241  {
1242  _DBUS_ASSERT_ERROR_IS_SET (error);
1243  return -1;
1244  }
1245 
1246  if (dbus_set_error_from_message (error, reply))
1247  {
1248  _DBUS_ASSERT_ERROR_IS_SET (error);
1249  dbus_message_unref (reply);
1250  return -1;
1251  }
1252 
1253  if (!dbus_message_get_args (reply, error,
1254  DBUS_TYPE_UINT32, &result,
1256  {
1257  _DBUS_ASSERT_ERROR_IS_SET (error);
1258  dbus_message_unref (reply);
1259  return -1;
1260  }
1261 
1262  dbus_message_unref (reply);
1263 
1264  return result;
1265 }
1266 
1286  const char *name,
1287  DBusError *error)
1288 {
1289  DBusMessage *message, *reply;
1290  dbus_bool_t exists;
1291 
1292  _dbus_return_val_if_fail (connection != NULL, FALSE);
1293  _dbus_return_val_if_fail (name != NULL, FALSE);
1294  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1295  _dbus_return_val_if_error_is_set (error, FALSE);
1296 
1300  "NameHasOwner");
1301  if (message == NULL)
1302  {
1303  _DBUS_SET_OOM (error);
1304  return FALSE;
1305  }
1306 
1307  if (!dbus_message_append_args (message,
1308  DBUS_TYPE_STRING, &name,
1310  {
1311  dbus_message_unref (message);
1312  _DBUS_SET_OOM (error);
1313  return FALSE;
1314  }
1315 
1316  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1317  dbus_message_unref (message);
1318 
1319  if (reply == NULL)
1320  {
1321  _DBUS_ASSERT_ERROR_IS_SET (error);
1322  return FALSE;
1323  }
1324 
1325  if (!dbus_message_get_args (reply, error,
1326  DBUS_TYPE_BOOLEAN, &exists,
1328  {
1329  _DBUS_ASSERT_ERROR_IS_SET (error);
1330  dbus_message_unref (reply);
1331  return FALSE;
1332  }
1333 
1334  dbus_message_unref (reply);
1335  return exists;
1336 }
1337 
1362  const char *name,
1363  dbus_uint32_t flags,
1364  dbus_uint32_t *result,
1365  DBusError *error)
1366 {
1367  DBusMessage *msg;
1368  DBusMessage *reply;
1369 
1370  _dbus_return_val_if_fail (connection != NULL, FALSE);
1371  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1372 
1376  "StartServiceByName");
1377 
1378  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1380  {
1381  dbus_message_unref (msg);
1382  _DBUS_SET_OOM (error);
1383  return FALSE;
1384  }
1385 
1386  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1387  -1, error);
1388  dbus_message_unref (msg);
1389 
1390  if (reply == NULL)
1391  {
1392  _DBUS_ASSERT_ERROR_IS_SET (error);
1393  return FALSE;
1394  }
1395 
1396  if (dbus_set_error_from_message (error, reply))
1397  {
1398  _DBUS_ASSERT_ERROR_IS_SET (error);
1399  dbus_message_unref (reply);
1400  return FALSE;
1401  }
1402 
1403  if (result != NULL &&
1404  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1405  result, DBUS_TYPE_INVALID))
1406  {
1407  _DBUS_ASSERT_ERROR_IS_SET (error);
1408  dbus_message_unref (reply);
1409  return FALSE;
1410  }
1411 
1412  dbus_message_unref (reply);
1413  return TRUE;
1414 }
1415 
1416 static void
1417 send_no_return_values (DBusConnection *connection,
1418  DBusMessage *msg,
1419  DBusError *error)
1420 {
1421  if (error)
1422  {
1423  /* Block to check success codepath */
1424  DBusMessage *reply;
1425 
1426  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1427  -1, error);
1428 
1429  if (reply == NULL)
1430  _DBUS_ASSERT_ERROR_IS_SET (error);
1431  else
1432  dbus_message_unref (reply);
1433  }
1434  else
1435  {
1436  /* Silently-fail nonblocking codepath */
1438  dbus_connection_send (connection, msg, NULL);
1439  }
1440 }
1441 
1530 void
1532  const char *rule,
1533  DBusError *error)
1534 {
1535  DBusMessage *msg;
1536 
1537  _dbus_return_if_fail (rule != NULL);
1538 
1542  "AddMatch");
1543 
1544  if (msg == NULL)
1545  {
1546  _DBUS_SET_OOM (error);
1547  return;
1548  }
1549 
1550  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1552  {
1553  dbus_message_unref (msg);
1554  _DBUS_SET_OOM (error);
1555  return;
1556  }
1557 
1558  send_no_return_values (connection, msg, error);
1559 
1560  dbus_message_unref (msg);
1561 }
1562 
1580 void
1582  const char *rule,
1583  DBusError *error)
1584 {
1585  DBusMessage *msg;
1586 
1587  _dbus_return_if_fail (rule != NULL);
1588 
1592  "RemoveMatch");
1593 
1594  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1596  {
1597  dbus_message_unref (msg);
1598  _DBUS_SET_OOM (error);
1599  return;
1600  }
1601 
1602  send_no_return_values (connection, msg, error);
1603 
1604  dbus_message_unref (msg);
1605 }
1606