D-Bus  1.4.10
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  /* The DBUS_SESSION_BUS_DEFAULT_ADDRESS should have really been named
196  * DBUS_SESSION_BUS_FALLBACK_ADDRESS.
197  */
198  if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
199  bus_connection_addresses[DBUS_BUS_SESSION] =
200  _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
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 DBusConnection *
425 internal_bus_get (DBusBusType type,
426  dbus_bool_t private,
427  DBusError *error)
428 {
429  const char *address;
430  DBusConnection *connection;
431  BusData *bd;
432  DBusBusType address_type;
433 
434  _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
435  _dbus_return_val_if_error_is_set (error, NULL);
436 
437  _DBUS_LOCK (bus);
438 
439  if (!init_connections_unlocked ())
440  {
441  _DBUS_UNLOCK (bus);
442  _DBUS_SET_OOM (error);
443  return NULL;
444  }
445 
446  /* We want to use the activation address even if the
447  * activating bus is the session or system bus,
448  * per the spec.
449  */
450  address_type = type;
451 
452  /* Use the real type of the activation bus for getting its
453  * connection, but only if the real type's address is available. (If
454  * the activating bus isn't a well-known bus then
455  * activation_bus_type == DBUS_BUS_STARTER)
456  */
457  if (type == DBUS_BUS_STARTER &&
458  bus_connection_addresses[activation_bus_type] != NULL)
459  type = activation_bus_type;
460 
461  if (!private && bus_connections[type] != NULL)
462  {
463  connection = bus_connections[type];
464  dbus_connection_ref (connection);
465 
466  _DBUS_UNLOCK (bus);
467  return connection;
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  _DBUS_UNLOCK (bus);
476  return NULL;
477  }
478 
479  if (private)
480  connection = dbus_connection_open_private (address, error);
481  else
482  connection = dbus_connection_open (address, error);
483 
484  if (!connection)
485  {
486  _DBUS_ASSERT_ERROR_IS_SET (error);
487  _DBUS_UNLOCK (bus);
488  return NULL;
489  }
490 
491  if (!dbus_bus_register (connection, error))
492  {
493  _DBUS_ASSERT_ERROR_IS_SET (error);
495  dbus_connection_unref (connection);
496 
497  _DBUS_UNLOCK (bus);
498  return NULL;
499  }
500 
501  if (!private)
502  {
503  /* store a weak ref to the connection (dbus-connection.c is
504  * supposed to have a strong ref that it drops on disconnect,
505  * since this is a shared connection)
506  */
507  bus_connections[type] = connection;
508  }
509 
510  /* By default we're bound to the lifecycle of
511  * the message bus.
512  */
514  TRUE);
515 
516  _DBUS_LOCK (bus_datas);
517  bd = ensure_bus_data (connection);
518  _dbus_assert (bd != NULL); /* it should have been created on
519  register, so OOM not possible */
520  bd->is_well_known = TRUE;
521  _DBUS_UNLOCK (bus_datas);
522 
523 
524  _DBUS_UNLOCK (bus);
525 
526  /* Return a reference to the caller */
527  return connection;
528 }
529 
530  /* end of implementation details docs */
532 
565  DBusError *error)
566 {
567  return internal_bus_get (type, FALSE, error);
568 }
569 
597  DBusError *error)
598 {
599  return internal_bus_get (type, TRUE, error);
600 }
601 
653  DBusError *error)
654 {
655  DBusMessage *message, *reply;
656  char *name;
657  BusData *bd;
658  dbus_bool_t retval;
659 
660  _dbus_return_val_if_fail (connection != NULL, FALSE);
661  _dbus_return_val_if_error_is_set (error, FALSE);
662 
663  retval = FALSE;
664 
665  _DBUS_LOCK (bus_datas);
666 
667  bd = ensure_bus_data (connection);
668  if (bd == NULL)
669  {
670  _DBUS_SET_OOM (error);
671  _DBUS_UNLOCK (bus_datas);
672  return FALSE;
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  _DBUS_UNLOCK (bus_datas);
680 
681  /* Success! */
682  return TRUE;
683  }
684 
688  "Hello");
689 
690  if (!message)
691  {
692  _DBUS_SET_OOM (error);
693 
694  _DBUS_UNLOCK (bus_datas);
695  return FALSE;
696  }
697 
698  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
699 
700  dbus_message_unref (message);
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  if (reply)
722  dbus_message_unref (reply);
723 
724  if (!retval)
725  _DBUS_ASSERT_ERROR_IS_SET (error);
726 
727  _DBUS_UNLOCK (bus_datas);
728 
729  return retval;
730 }
731 
732 
769  const char *unique_name)
770 {
771  BusData *bd;
772  dbus_bool_t success = FALSE;
773 
774  _dbus_return_val_if_fail (connection != NULL, FALSE);
775  _dbus_return_val_if_fail (unique_name != NULL, FALSE);
776 
777  _DBUS_LOCK (bus_datas);
778 
779  bd = ensure_bus_data (connection);
780  if (bd == NULL)
781  goto out;
782 
783  _dbus_assert (bd->unique_name == NULL);
784 
785  bd->unique_name = _dbus_strdup (unique_name);
786  success = bd->unique_name != NULL;
787 
788 out:
789  _DBUS_UNLOCK (bus_datas);
790 
791  return success;
792 }
793 
812 const char*
814 {
815  BusData *bd;
816  const char *unique_name = NULL;
817 
818  _dbus_return_val_if_fail (connection != NULL, NULL);
819 
820  _DBUS_LOCK (bus_datas);
821 
822  bd = ensure_bus_data (connection);
823  if (bd == NULL)
824  goto out;
825 
826  unique_name = bd->unique_name;
827 
828 out:
829  _DBUS_UNLOCK (bus_datas);
830 
831  return unique_name;
832 }
833 
857 unsigned long
859  const char *name,
860  DBusError *error)
861 {
862  DBusMessage *message, *reply;
863  dbus_uint32_t uid;
864 
865  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
866  _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
867  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
868  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
869 
873  "GetConnectionUnixUser");
874 
875  if (message == NULL)
876  {
877  _DBUS_SET_OOM (error);
878  return DBUS_UID_UNSET;
879  }
880 
881  if (!dbus_message_append_args (message,
882  DBUS_TYPE_STRING, &name,
884  {
885  dbus_message_unref (message);
886  _DBUS_SET_OOM (error);
887  return DBUS_UID_UNSET;
888  }
889 
890  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
891  error);
892 
893  dbus_message_unref (message);
894 
895  if (reply == NULL)
896  {
897  _DBUS_ASSERT_ERROR_IS_SET (error);
898  return DBUS_UID_UNSET;
899  }
900 
901  if (dbus_set_error_from_message (error, reply))
902  {
903  _DBUS_ASSERT_ERROR_IS_SET (error);
904  dbus_message_unref (reply);
905  return DBUS_UID_UNSET;
906  }
907 
908  if (!dbus_message_get_args (reply, error,
909  DBUS_TYPE_UINT32, &uid,
911  {
912  _DBUS_ASSERT_ERROR_IS_SET (error);
913  dbus_message_unref (reply);
914  return DBUS_UID_UNSET;
915  }
916 
917  dbus_message_unref (reply);
918 
919  return (unsigned long) uid;
920 }
921 
940 char*
942  DBusError *error)
943 {
944  DBusMessage *message, *reply;
945  char *id;
946  const char *v_STRING;
947 
948  _dbus_return_val_if_fail (connection != NULL, NULL);
949  _dbus_return_val_if_error_is_set (error, NULL);
950 
954  "GetId");
955 
956  if (message == NULL)
957  {
958  _DBUS_SET_OOM (error);
959  return NULL;
960  }
961 
962  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
963  error);
964 
965  dbus_message_unref (message);
966 
967  if (reply == NULL)
968  {
969  _DBUS_ASSERT_ERROR_IS_SET (error);
970  return NULL;
971  }
972 
973  if (dbus_set_error_from_message (error, reply))
974  {
975  _DBUS_ASSERT_ERROR_IS_SET (error);
976  dbus_message_unref (reply);
977  return NULL;
978  }
979 
980  v_STRING = NULL;
981  if (!dbus_message_get_args (reply, error,
982  DBUS_TYPE_STRING, &v_STRING,
984  {
985  _DBUS_ASSERT_ERROR_IS_SET (error);
986  dbus_message_unref (reply);
987  return NULL;
988  }
989 
990  id = _dbus_strdup (v_STRING); /* may be NULL */
991 
992  dbus_message_unref (reply);
993 
994  if (id == NULL)
995  _DBUS_SET_OOM (error);
996 
997  /* FIXME it might be nice to cache the ID locally */
998 
999  return id;
1000 }
1001 
1104 int
1106  const char *name,
1107  unsigned int flags,
1108  DBusError *error)
1109 {
1110  DBusMessage *message, *reply;
1111  dbus_uint32_t result;
1112 
1113  _dbus_return_val_if_fail (connection != NULL, 0);
1114  _dbus_return_val_if_fail (name != NULL, 0);
1115  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1116  _dbus_return_val_if_error_is_set (error, 0);
1117 
1121  "RequestName");
1122 
1123  if (message == NULL)
1124  {
1125  _DBUS_SET_OOM (error);
1126  return -1;
1127  }
1128 
1129  if (!dbus_message_append_args (message,
1130  DBUS_TYPE_STRING, &name,
1131  DBUS_TYPE_UINT32, &flags,
1133  {
1134  dbus_message_unref (message);
1135  _DBUS_SET_OOM (error);
1136  return -1;
1137  }
1138 
1139  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1140  error);
1141 
1142  dbus_message_unref (message);
1143 
1144  if (reply == NULL)
1145  {
1146  _DBUS_ASSERT_ERROR_IS_SET (error);
1147  return -1;
1148  }
1149 
1150  if (dbus_set_error_from_message (error, reply))
1151  {
1152  _DBUS_ASSERT_ERROR_IS_SET (error);
1153  dbus_message_unref (reply);
1154  return -1;
1155  }
1156 
1157  if (!dbus_message_get_args (reply, error,
1158  DBUS_TYPE_UINT32, &result,
1160  {
1161  _DBUS_ASSERT_ERROR_IS_SET (error);
1162  dbus_message_unref (reply);
1163  return -1;
1164  }
1165 
1166  dbus_message_unref (reply);
1167 
1168  return result;
1169 }
1170 
1171 
1190 int
1192  const char *name,
1193  DBusError *error)
1194 {
1195  DBusMessage *message, *reply;
1196  dbus_uint32_t result;
1197 
1198  _dbus_return_val_if_fail (connection != NULL, 0);
1199  _dbus_return_val_if_fail (name != NULL, 0);
1200  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1201  _dbus_return_val_if_error_is_set (error, 0);
1202 
1206  "ReleaseName");
1207 
1208  if (message == NULL)
1209  {
1210  _DBUS_SET_OOM (error);
1211  return -1;
1212  }
1213 
1214  if (!dbus_message_append_args (message,
1215  DBUS_TYPE_STRING, &name,
1217  {
1218  dbus_message_unref (message);
1219  _DBUS_SET_OOM (error);
1220  return -1;
1221  }
1222 
1223  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1224  error);
1225 
1226  dbus_message_unref (message);
1227 
1228  if (reply == NULL)
1229  {
1230  _DBUS_ASSERT_ERROR_IS_SET (error);
1231  return -1;
1232  }
1233 
1234  if (dbus_set_error_from_message (error, reply))
1235  {
1236  _DBUS_ASSERT_ERROR_IS_SET (error);
1237  dbus_message_unref (reply);
1238  return -1;
1239  }
1240 
1241  if (!dbus_message_get_args (reply, error,
1242  DBUS_TYPE_UINT32, &result,
1244  {
1245  _DBUS_ASSERT_ERROR_IS_SET (error);
1246  dbus_message_unref (reply);
1247  return -1;
1248  }
1249 
1250  dbus_message_unref (reply);
1251 
1252  return result;
1253 }
1254 
1274  const char *name,
1275  DBusError *error)
1276 {
1277  DBusMessage *message, *reply;
1278  dbus_bool_t exists;
1279 
1280  _dbus_return_val_if_fail (connection != NULL, FALSE);
1281  _dbus_return_val_if_fail (name != NULL, FALSE);
1282  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1283  _dbus_return_val_if_error_is_set (error, FALSE);
1284 
1288  "NameHasOwner");
1289  if (message == NULL)
1290  {
1291  _DBUS_SET_OOM (error);
1292  return FALSE;
1293  }
1294 
1295  if (!dbus_message_append_args (message,
1296  DBUS_TYPE_STRING, &name,
1298  {
1299  dbus_message_unref (message);
1300  _DBUS_SET_OOM (error);
1301  return FALSE;
1302  }
1303 
1304  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1305  dbus_message_unref (message);
1306 
1307  if (reply == NULL)
1308  {
1309  _DBUS_ASSERT_ERROR_IS_SET (error);
1310  return FALSE;
1311  }
1312 
1313  if (!dbus_message_get_args (reply, error,
1314  DBUS_TYPE_BOOLEAN, &exists,
1316  {
1317  _DBUS_ASSERT_ERROR_IS_SET (error);
1318  dbus_message_unref (reply);
1319  return FALSE;
1320  }
1321 
1322  dbus_message_unref (reply);
1323  return exists;
1324 }
1325 
1350  const char *name,
1351  dbus_uint32_t flags,
1352  dbus_uint32_t *result,
1353  DBusError *error)
1354 {
1355  DBusMessage *msg;
1356  DBusMessage *reply;
1357 
1358  _dbus_return_val_if_fail (connection != NULL, FALSE);
1359  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1360 
1364  "StartServiceByName");
1365 
1366  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1368  {
1369  dbus_message_unref (msg);
1370  _DBUS_SET_OOM (error);
1371  return FALSE;
1372  }
1373 
1374  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1375  -1, error);
1376  dbus_message_unref (msg);
1377 
1378  if (reply == NULL)
1379  {
1380  _DBUS_ASSERT_ERROR_IS_SET (error);
1381  return FALSE;
1382  }
1383 
1384  if (dbus_set_error_from_message (error, reply))
1385  {
1386  _DBUS_ASSERT_ERROR_IS_SET (error);
1387  dbus_message_unref (reply);
1388  return FALSE;
1389  }
1390 
1391  if (result != NULL &&
1392  !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1393  result, DBUS_TYPE_INVALID))
1394  {
1395  _DBUS_ASSERT_ERROR_IS_SET (error);
1396  dbus_message_unref (reply);
1397  return FALSE;
1398  }
1399 
1400  dbus_message_unref (reply);
1401  return TRUE;
1402 }
1403 
1404 static void
1405 send_no_return_values (DBusConnection *connection,
1406  DBusMessage *msg,
1407  DBusError *error)
1408 {
1409  if (error)
1410  {
1411  /* Block to check success codepath */
1412  DBusMessage *reply;
1413 
1414  reply = dbus_connection_send_with_reply_and_block (connection, msg,
1415  -1, error);
1416 
1417  if (reply == NULL)
1418  _DBUS_ASSERT_ERROR_IS_SET (error);
1419  else
1420  dbus_message_unref (reply);
1421  }
1422  else
1423  {
1424  /* Silently-fail nonblocking codepath */
1426  dbus_connection_send (connection, msg, NULL);
1427  }
1428 }
1429 
1512 void
1514  const char *rule,
1515  DBusError *error)
1516 {
1517  DBusMessage *msg;
1518 
1519  _dbus_return_if_fail (rule != NULL);
1520 
1524  "AddMatch");
1525 
1526  if (msg == NULL)
1527  {
1528  _DBUS_SET_OOM (error);
1529  return;
1530  }
1531 
1532  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1534  {
1535  dbus_message_unref (msg);
1536  _DBUS_SET_OOM (error);
1537  return;
1538  }
1539 
1540  send_no_return_values (connection, msg, error);
1541 
1542  dbus_message_unref (msg);
1543 }
1544 
1562 void
1564  const char *rule,
1565  DBusError *error)
1566 {
1567  DBusMessage *msg;
1568 
1569  _dbus_return_if_fail (rule != NULL);
1570 
1574  "RemoveMatch");
1575 
1576  if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1578  {
1579  dbus_message_unref (msg);
1580  _DBUS_SET_OOM (error);
1581  return;
1582  }
1583 
1584  send_no_return_values (connection, msg, error);
1585 
1586  dbus_message_unref (msg);
1587 }
1588