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