dbus/dbus Makefile.am, 1.83, 1.84 dbus-connection.c, 1.134, 1.135 dbus-connection.h, 1.43, 1.44 dbus-internals.c, 1.48, 1.49 dbus-internals.h, 1.60, 1.61 dbus-protocol.h, 1.46, 1.47 dbus-server-protected.h, 1.22, 1.23 dbus-server.c, 1.48, 1.49 dbus-string-private.h, 1.7, 1.8 dbus-string-util.c, 1.3, 1.4 dbus-string.c, 1.72, 1.73 dbus-string.h, 1.40, 1.41 dbus-sysdeps-unix.c, 1.6, 1.7 dbus-sysdeps.c, 1.113, 1.114 dbus-sysdeps.h, 1.60, 1.61 dbus-threads.c, 1.29, 1.30 dbus-uuidgen.c, NONE, 1.1 dbus-uuidgen.h, NONE, 1.1

Havoc Pennington hp at kemper.freedesktop.org
Sat Sep 30 20:18:49 PDT 2006


Update of /cvs/dbus/dbus/dbus
In directory kemper:/tmp/cvs-serv15792/dbus

Modified Files:
	Makefile.am dbus-connection.c dbus-connection.h 
	dbus-internals.c dbus-internals.h dbus-protocol.h 
	dbus-server-protected.h dbus-server.c dbus-string-private.h 
	dbus-string-util.c dbus-string.c dbus-string.h 
	dbus-sysdeps-unix.c dbus-sysdeps.c dbus-sysdeps.h 
	dbus-threads.c 
Added Files:
	dbus-uuidgen.c dbus-uuidgen.h 
Log Message:
2006-09-30  Havoc Pennington  <hp at redhat.com>

	* configure.in (LT_CURRENT, LT_AGE): increment current and age to
	reflect addition of interfaces.

	* doc/dbus-specification.xml: describe a new
	org.freedesktop.DBus.Peer.GetMachineId method

	* dbus/dbus-string.c (_dbus_string_skip_white_reverse): new function
	(_dbus_string_skip_white, _dbus_string_skip_blank): use new
	DBUS_IS_ASCII_BLANK, DBUS_IS_ASCII_WHITE macros and fix assertion
	at end of skip_white
	(_dbus_string_chop_white): new function

	* bus/connection.c (bus_connections_setup_connection): call
	dbus_connection_set_route_peer_messages.

	* dbus/dbus-connection.c
	(_dbus_connection_peer_filter_unlocked_no_update): modify to
	support a GetMachineId method.

	Also, support a new flag to let the bus pass peer methods through
	to apps on the bus, which can be set with
	dbus_connection_set_route_peer_messages.

	Finally, handle and return an error for anything unknown on the
	Peer interface, which will allow us to extend the Peer interface
	in the future without fear that we're now intercepting something
	apps were wanting to see.
	
	* tools/dbus-uuidgen.c: a thin wrapper around the functions in 
	dbus/dbus-uuidgen.c

	* dbus/dbus-uuidgen.c: implement the bulk of the dbus-uuidgen
	binary here, since most of the code is already in libdbus

	* dbus/dbus-sysdeps.c (_dbus_read_local_machine_uuid): read the
	uuid from the system config file

	* dbus/dbus-internals.c (_dbus_generate_uuid, _dbus_uuid_encode) 
	(_dbus_read_uuid_file_without_creating) 
	(_dbus_create_uuid_file_exclusively, _dbus_read_uuid_file): new
	uuid-related functions, partly factored out from dbus-server.c

	* dbus/dbus-sysdeps.c (_dbus_error_from_errno): convert EEXIST to
	DBUS_ERROR_FILE_EXISTS instead of EEXIST

	* dbus/dbus-protocol.h (DBUS_ERROR_FILE_EXISTS): add file exists error

	* tools/dbus-cleanup-sockets.1: explain what the point of this
	thing is a bit more

	* autogen.sh (run_configure): add --config-cache to default
	configure args

	* dbus/dbus-internals.h (_DBUS_ASSERT_ERROR_IS_SET): disable the
	error set/clear assertions when DBUS_DISABLE_CHECKS is defined

	* tools/dbus-launch.c (main): if xdisplay hasn't been opened,
	don't try to save address, fixes crash in make check



Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/dbus/Makefile.am,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- Makefile.am	16 Sep 2006 17:38:24 -0000	1.83
+++ Makefile.am	1 Oct 2006 03:18:47 -0000	1.84
@@ -1,5 +1,7 @@
 
-INCLUDES=-I$(top_builddir) -I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) -DDBUS_COMPILATION
+configdir=$(sysconfdir)/dbus-1
+
+INCLUDES=-I$(top_builddir) -I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) -DDBUS_COMPILATION -DDBUS_MACHINE_UUID_FILE=\""$(configdir)/machine-id"\"
 
 dbusincludedir=$(includedir)/dbus-1.0/dbus
 dbusarchincludedir=$(libdir)/dbus-1.0/include/dbus
@@ -80,6 +82,8 @@
 	dbus-transport-socket.h			\
 	dbus-transport-unix.c			\
 	dbus-transport-unix.h			\
+	dbus-uuidgen.c				\
+	dbus-uuidgen.h				\
 	dbus-watch.c				\
 	dbus-watch.h
 

Index: dbus-connection.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.c,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -d -r1.134 -r1.135
--- dbus-connection.c	30 Sep 2006 19:38:34 -0000	1.134
+++ dbus-connection.c	1 Oct 2006 03:18:47 -0000	1.135
@@ -1,7 +1,7 @@
 /* -*- mode: C; c-file-style: "gnu" -*- */
 /* dbus-connection.c DBusConnection object
  *
- * Copyright (C) 2002, 2003, 2004, 2005  Red Hat Inc.
+ * Copyright (C) 2002-2006  Red Hat Inc.
  *
  * Licensed under the Academic Free License version 2.1
  * 
@@ -246,6 +246,8 @@
   unsigned int io_path_acquired : 1;  /**< Someone has transport io path (can use the transport to read/write messages) */
   
   unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
+
+  unsigned int route_peer_messages : 1; /**< If #TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don't handle them automatically */
   
 #ifndef DBUS_DISABLE_CHECKS
   unsigned int have_connection_lock : 1; /**< Used to check locking */
@@ -1175,6 +1177,8 @@
   connection->objects = objects;
   connection->exit_on_disconnect = FALSE;
   connection->shareable = FALSE;
+  connection->route_peer_messages = FALSE;
+  
 #ifndef DBUS_DISABLE_CHECKS
   connection->generation = _dbus_current_generation;
 #endif
@@ -3575,15 +3579,20 @@
 }
 
 /**
-* Filter funtion for handling the Peer standard interface
-**/
+ * Filter funtion for handling the Peer standard interface.
+ */
 static DBusHandlerResult
 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
                                                  DBusMessage    *message)
 {
-  if (dbus_message_is_method_call (message,
-                                   DBUS_INTERFACE_PEER,
-                                   "Ping"))
+  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
+    {
+      /* This means we're letting the bus route this message */
+      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+  else if (dbus_message_is_method_call (message,
+                                        DBUS_INTERFACE_PEER,
+                                        "Ping"))
     {
       DBusMessage *ret;
       dbus_bool_t sent;
@@ -3601,9 +3610,68 @@
       
       return DBUS_HANDLER_RESULT_HANDLED;
     }
-                                   
-  
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  else if (dbus_message_is_method_call (message,
+                                        DBUS_INTERFACE_PEER,
+                                        "GetMachineId"))
+    {
+      DBusMessage *ret;
+      dbus_bool_t sent;
+      DBusString uuid;
+      
+      ret = dbus_message_new_method_return (message);
+      if (ret == NULL)
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+      sent = FALSE;
+      _dbus_string_init (&uuid);
+      if (_dbus_get_local_machine_uuid_encoded (&uuid))
+        {
+          const char *v_STRING = _dbus_string_get_const_data (&uuid);
+          if (dbus_message_append_args (ret,
+                                        DBUS_TYPE_STRING, &v_STRING,
+                                        DBUS_TYPE_INVALID))
+            {
+              sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
+            }
+        }
+      _dbus_string_free (&uuid);
+      
+      dbus_message_unref (ret);
+
+      if (!sent)
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+      
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
+  else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
+    {
+      /* We need to bounce anything else with this interface, otherwise apps
+       * could start extending the interface and when we added extensions
+       * here to DBusConnection we'd break those apps.
+       */
+      
+      DBusMessage *ret;
+      dbus_bool_t sent;
+      
+      ret = dbus_message_new_error (message,
+                                    DBUS_ERROR_UNKNOWN_METHOD,
+                                    "Unknown method invoked on org.freedesktop.DBus.Peer interface");
+      if (ret == NULL)
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+      
+      sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
+      
+      dbus_message_unref (ret);
+      
+      if (!sent)
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+      
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
+  else
+    {
+      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
 }
 
 /**
@@ -4409,6 +4477,35 @@
 }
 
 /**
+ *
+ * Normally #DBusConnection automatically handles all messages to the
+ * org.freedesktop.DBus.Peer interface. However, the message bus wants
+ * to be able to route methods on that interface through the bus and
+ * to other applications. If routing peer messages is enabled, then
+ * messages with the org.freedesktop.DBus.Peer interface that also
+ * have a bus destination name set will not be automatically
+ * handled by the #DBusConnection and instead will be dispatched
+ * normally to the application.
+ *
+ *
+ * If a normal application sets this flag, it can break things badly.
+ * So don't set this unless you are the message bus.
+ *
+ * @param connection the connection
+ * @param value #TRUE to pass through org.freedesktop.DBus.Peer messages with a bus name set
+ */
+void
+dbus_connection_set_route_peer_messages (DBusConnection             *connection,
+                                         dbus_bool_t                 value)
+{
+  _dbus_return_if_fail (connection != NULL);
+  
+  CONNECTION_LOCK (connection);
+  connection->route_peer_messages = TRUE;
+  CONNECTION_UNLOCK (connection);
+}
+
+/**
  * Adds a message filter. Filters are handlers that are run on all
  * incoming messages, prior to the objects registered with
  * dbus_connection_register_object_path().  Filters are run in the
@@ -4968,4 +5065,58 @@
   return res;
 }
 
+/**
+ * Obtains the machine UUID of the machine this process is running on.
+ *
+ * The returned string must be freed with dbus_free().
+ * 
+ * This UUID is guaranteed to remain the same until the next reboot
+ * (unless the sysadmin foolishly changes it and screws themselves).
+ * It will usually remain the same across reboots also, but hardware
+ * configuration changes or rebuilding the machine could break that.
+ *
+ * The idea is that two processes with the same machine ID should be
+ * able to use shared memory, UNIX domain sockets, process IDs, and other
+ * features of the OS that require both processes to be running
+ * on the same OS kernel instance.
+ *
+ * The machine ID can also be used to create unique per-machine
+ * instances. For example, you could use it in bus names or
+ * X selection names.
+ *
+ * The machine ID is preferred over the machine hostname, because
+ * the hostname is frequently set to "localhost.localdomain" and
+ * may also change at runtime.
+ *
+ * You can get the machine ID of a remote application by invoking the
+ * method GetMachineId from interface org.freedesktop.DBus.Peer.
+ *
+ * If the remote application has the same machine ID as the one
+ * returned by this function, then the remote application is on the
+ * same machine as your application.
+ * 
+ * @returns a 32-byte-long hex-encoded UUID string, or #NULL if insufficient memory
+ */
+char*
+dbus_get_local_machine_id (void)
+{
+  DBusString uuid;
+  char *s;
+
+  s = NULL;
+  _dbus_string_init (&uuid);
+  if (!_dbus_get_local_machine_uuid_encoded (&uuid) ||
+      !_dbus_string_steal_data (&uuid, &s))
+    {
+      _dbus_string_free (&uuid);
+      return FALSE;
+    }
+  else
+    {
+      _dbus_string_free (&uuid);
+      return s;
+    }
+
+}
+
 /** @} */

Index: dbus-connection.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- dbus-connection.h	16 Sep 2006 18:46:48 -0000	1.43
+++ dbus-connection.h	1 Oct 2006 03:18:47 -0000	1.44
@@ -151,6 +151,8 @@
                                                                  DBusAllowUnixUserFunction   function,
                                                                  void                       *data,
                                                                  DBusFreeFunction            free_data_function);
+void               dbus_connection_set_route_peer_messages      (DBusConnection             *connection,
+                                                                 dbus_bool_t                 value);
 
 
 int          dbus_watch_get_fd      (DBusWatch        *watch);
@@ -258,6 +260,8 @@
 dbus_bool_t dbus_connection_get_socket             (DBusConnection              *connection,
                                                     int                         *fd);
 
+char*       dbus_get_local_machine_id              (void);
+
 DBUS_END_DECLS
 
 #endif /* DBUS_CONNECTION_H */

Index: dbus-internals.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- dbus-internals.c	16 Sep 2006 17:38:24 -0000	1.48
+++ dbus-internals.c	1 Oct 2006 03:18:47 -0000	1.49
@@ -413,6 +413,258 @@
   return FALSE;
 }
 
+/**
+ * Generates a new UUID. If you change how this is done,
+ * there's some text about it in the spec that should also change.
+ *
+ * @param uuid the uuid to initialize
+ */
+void
+_dbus_generate_uuid (DBusGUID *uuid)
+{
+  long now;
+  char *p;
+  int ts_size;
+
+  _dbus_get_current_time (&now, NULL);
+
+  uuid->as_uint32s[0] = now;
+
+  ts_size = sizeof (uuid->as_uint32s[0]);
+  p = ((char*)uuid->as_bytes) + ts_size;
+  
+  _dbus_generate_random_bytes_buffer (p,
+                                      sizeof (uuid->as_bytes) - ts_size);
+}
+
+/**
+ * Hex-encode a UUID.
+ *
+ * @param uuid the uuid
+ * @param encoded string to append hex uuid to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_uuid_encode (const DBusGUID *uuid,
+                   DBusString     *encoded)
+{
+  DBusString binary;
+  _dbus_string_init_const_len (&binary, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES);
+  return _dbus_string_hex_encode (&binary, 0, encoded, _dbus_string_get_length (encoded));
+}
+
+static dbus_bool_t
+_dbus_read_uuid_file_without_creating (const DBusString *filename,
+                                       DBusGUID         *uuid,
+                                       DBusError        *error)
+{
+  DBusString contents;
+  DBusString decoded;
+  int end;
+  
+  _dbus_string_init (&contents);
+  _dbus_string_init (&decoded);
+  
+  if (!_dbus_file_get_contents (&contents, filename, error))
+    goto error;
+
+  _dbus_string_chop_white (&contents);
+
+  if (_dbus_string_get_length (&contents) != DBUS_UUID_LENGTH_HEX)
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
+                      "UUID file '%s' should contain a hex string of length %d, not length %d, with no other text",
+                      _dbus_string_get_const_data (filename),
+                      DBUS_UUID_LENGTH_HEX,
+                      _dbus_string_get_length (&contents));
+      goto error;
+    }
+
+  if (!_dbus_string_hex_decode (&contents, 0, &end, &decoded, 0))
+    {
+      _DBUS_SET_OOM (error);
+      goto error;
+    }
+
+  if (end == 0)
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
+                      "UUID file '%s' contains invalid hex data",
+                      _dbus_string_get_const_data (filename));
+      goto error;
+    }
+
+  if (_dbus_string_get_length (&decoded) != DBUS_UUID_LENGTH_BYTES)
+    {
+      dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
+                      "UUID file '%s' contains %d bytes of hex-encoded data instead of %d",
+                      _dbus_string_get_const_data (filename),
+                      _dbus_string_get_length (&decoded),
+                      DBUS_UUID_LENGTH_BYTES);
+      goto error;
+    }
+
+  _dbus_string_copy_to_buffer (&decoded, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES);
+
+  _dbus_string_free (&decoded);
+  _dbus_string_free (&contents);
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  return TRUE;
+  
+ error:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  _dbus_string_free (&contents);
+  _dbus_string_free (&decoded);
+  return FALSE;
+}
+
+static dbus_bool_t
+_dbus_create_uuid_file_exclusively (const DBusString *filename,
+                                    DBusGUID         *uuid,
+                                    DBusError        *error)
+{
+  DBusString encoded;
+
+  _dbus_string_init (&encoded);
+
+  _dbus_generate_uuid (uuid);
+  
+  if (!_dbus_uuid_encode (uuid, &encoded))
+    {
+      _DBUS_SET_OOM (error);
+      goto error;
+    }
+  
+  /* FIXME this is racy; we need a save_file_exclusively
+   * function. But in practice this should be fine for now.
+   *
+   * - first be sure we can create the file and it
+   *   doesn't exist by creating it empty with O_EXCL
+   * - then create it by creating a temporary file and
+   *   overwriting atomically with rename()
+   */
+  if (!_dbus_create_file_exclusively (filename, error))
+    goto error;
+
+  if (!_dbus_string_append_byte (&encoded, '\n'))
+    {
+      _DBUS_SET_OOM (error);
+      goto error;
+    }
+  
+  if (!_dbus_string_save_to_file (&encoded, filename, error))
+    goto error;
+
+
+  _dbus_string_free (&encoded);
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  return TRUE;
+  
+ error:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  _dbus_string_free (&encoded);
+  return FALSE;        
+}
+
+/**
+ * Reads (and optionally writes) a uuid to a file. Initializes the uuid
+ * unless an error is returned.
+ *
+ * @param filename the name of the file
+ * @param uuid uuid to be initialized with the loaded uuid
+ * @param create_if_not_found #TRUE to create a new uuid and save it if the file doesn't exist
+ * @param error the error return
+ * @returns #FALSE if the error is set
+ */
+dbus_bool_t
+_dbus_read_uuid_file (const DBusString *filename,
+                      DBusGUID         *uuid,
+                      dbus_bool_t       create_if_not_found,
+                      DBusError        *error)
+{
+  DBusError read_error;
+
+  dbus_error_init (&read_error);
+
+  if (_dbus_read_uuid_file_without_creating (filename, uuid, &read_error))
+    return TRUE;
+
+  if (!create_if_not_found)
+    {
+      dbus_move_error (&read_error, error);
+      return FALSE;
+    }
+
+  /* If the file exists and contains junk, we want to keep that error
+   * message instead of overwriting it with a "file exists" error
+   * message when we try to write
+   */
+  if (dbus_error_has_name (&read_error, DBUS_ERROR_INVALID_FILE_CONTENT))
+    {
+      dbus_move_error (&read_error, error);
+      return FALSE;
+    }
+  else
+    {
+      dbus_error_free (&read_error);
+      return _dbus_create_uuid_file_exclusively (filename, uuid, error);
+    }
+}
+
+_DBUS_DEFINE_GLOBAL_LOCK (machine_uuid);
+static int machine_uuid_initialized_generation = 0;
+static DBusGUID machine_uuid;
+
+/**
+ * Gets the hex-encoded UUID of the machine this function is
+ * executed on. This UUID is guaranteed to be the same for a given
+ * machine at least until it next reboots, though it also
+ * makes some effort to be the same forever, it may change if the
+ * machine is reconfigured or its hardware is modified.
+ * 
+ * @param uuid_str string to append hex-encoded machine uuid to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
+{
+  dbus_bool_t ok;
+  
+  _DBUS_LOCK (machine_uuid);
+  if (machine_uuid_initialized_generation != _dbus_current_generation)
+    {
+      DBusError error;
+      dbus_error_init (&error);
+      if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE,
+                                          &error))
+        {          
+#ifndef DBUS_BUILD_TESTS
+          /* For the test suite, we may not be installed so just continue silently
+           * here. But in a production build, we want to be nice and loud about
+           * this.
+           */
+          _dbus_warn ("D-Bus library appears to be incorrectly set up; failed to read machine uuid: %s\n",
+                      error.message);
+          _dbus_warn ("See the manual page for dbus-uuidgen to correct this issue.\n");
+          _dbus_warn ("Continuing with a bogus made-up machine UUID, which may cause problems.");
+#endif
+          
+          dbus_error_free (&error);
+          
+          _dbus_generate_uuid (&machine_uuid);
+        }
+    }
+
+  ok = _dbus_uuid_encode (&machine_uuid, uuid_str);
+
+  _DBUS_UNLOCK (machine_uuid);
+
+  return ok;
+}
+
 #ifdef DBUS_BUILD_TESTS
 /**
  * Returns a string describing the given name.

Index: dbus-internals.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- dbus-internals.h	30 Sep 2006 19:38:34 -0000	1.60
+++ dbus-internals.h	1 Oct 2006 03:18:47 -0000	1.61
@@ -157,8 +157,16 @@
 #define _DBUS_STRUCT_OFFSET(struct_type, member)	\
     ((long) ((unsigned char*) &((struct_type*) 0)->member))
 
+#ifdef DBUS_DISABLE_CHECKS
+/* this is an assert and not an error, but in the typical --disable-checks case (you're trying
+ * to really minimize code size), disabling these assertions makes sense.
+ */
+#define _DBUS_ASSERT_ERROR_IS_SET(error)
+#define _DBUS_ASSERT_ERROR_IS_CLEAR(error)
+#else
 #define _DBUS_ASSERT_ERROR_IS_SET(error)   _dbus_assert ((error) == NULL || dbus_error_is_set ((error)))
 #define _DBUS_ASSERT_ERROR_IS_CLEAR(error) _dbus_assert ((error) == NULL || !dbus_error_is_set ((error)))
+#endif
 
 #define _dbus_return_if_error_is_set(error) _dbus_return_if_fail ((error) == NULL || !dbus_error_is_set ((error)))
 #define _dbus_return_val_if_error_is_set(error, val) _dbus_return_val_if_fail ((error) == NULL || !dbus_error_is_set ((error)), (val))
@@ -288,7 +296,8 @@
 _DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
 _DBUS_DECLARE_GLOBAL_LOCK (win_fds);
 _DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);
-#define _DBUS_N_GLOBAL_LOCKS (13)
+_DBUS_DECLARE_GLOBAL_LOCK (machine_uuid);
+#define _DBUS_N_GLOBAL_LOCKS (14)
 
 dbus_bool_t _dbus_threads_init_debug (void);
 
@@ -300,6 +309,28 @@
                                             const char        *address_problem_field,
                                             const char        *address_problem_other);
 
+#define DBUS_UUID_LENGTH_BYTES 16
+#define DBUS_UUID_LENGTH_HEX (DBUS_UUID_LENGTH_BYTES * 2)
+
+/**
+ * A globally unique ID ; we have one for each DBusServer, and also one for each
+ * machine with libdbus installed on it.
+ */
+union DBusGUID
+{
+  dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_BYTES / 4];
+  char as_bytes[DBUS_UUID_LENGTH_BYTES];
+};
+
+void        _dbus_generate_uuid  (DBusGUID         *uuid);
+dbus_bool_t _dbus_uuid_encode    (const DBusGUID   *uuid,
+                                  DBusString       *encoded);
+dbus_bool_t _dbus_read_uuid_file (const DBusString *filename,
+                                  DBusGUID         *uuid,
+                                  dbus_bool_t       create_if_not_found,
+                                  DBusError        *error);
+
+dbus_bool_t _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str);
 
 DBUS_END_DECLS
 

Index: dbus-protocol.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-protocol.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- dbus-protocol.h	19 Dec 2005 23:58:22 -0000	1.46
+++ dbus-protocol.h	1 Oct 2006 03:18:47 -0000	1.47
@@ -242,6 +242,7 @@
 #define DBUS_ERROR_DISCONNECTED               "org.freedesktop.DBus.Error.Disconnected"
 #define DBUS_ERROR_INVALID_ARGS               "org.freedesktop.DBus.Error.InvalidArgs"
 #define DBUS_ERROR_FILE_NOT_FOUND             "org.freedesktop.DBus.Error.FileNotFound"
+#define DBUS_ERROR_FILE_EXISTS                "org.freedesktop.DBus.Error.FileExists"
 #define DBUS_ERROR_UNKNOWN_METHOD             "org.freedesktop.DBus.Error.UnknownMethod"
 #define DBUS_ERROR_TIMED_OUT                  "org.freedesktop.DBus.Error.TimedOut"
 #define DBUS_ERROR_MATCH_RULE_NOT_FOUND       "org.freedesktop.DBus.Error.MatchRuleNotFound"
@@ -253,6 +254,7 @@
 #define DBUS_ERROR_SPAWN_FAILED               "org.freedesktop.DBus.Error.Spawn.Failed"
 #define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN    "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
 #define DBUS_ERROR_INVALID_SIGNATURE          "org.freedesktop.DBus.Error.InvalidSignature"
+#define DBUS_ERROR_INVALID_FILE_CONTENT       "org.freedesktop.DBus.Error.InvalidFileContent"
 #define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN    "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
 
 #define DBUS_INTROSPECT_1_0_XML_NAMESPACE         "http://www.freedesktop.org/standards/dbus"

Index: dbus-server-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-protected.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- dbus-server-protected.h	16 Sep 2006 19:24:08 -0000	1.22
+++ dbus-server-protected.h	1 Oct 2006 03:18:47 -0000	1.23
@@ -37,16 +37,6 @@
 DBUS_BEGIN_DECLS
 
 typedef struct DBusServerVTable DBusServerVTable;
-typedef union DBusGUID DBusGUID;
-
-/**
- * A server's globally unique ID
- */
-union DBusGUID
-{
-  dbus_uint32_t as_uint32s[4];
-  unsigned char as_bytes[16];
-};
 
 /**
  * Virtual table to be implemented by all server "subclasses"

Index: dbus-server.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- dbus-server.c	16 Sep 2006 19:24:08 -0000	1.48
+++ dbus-server.c	1 Oct 2006 03:18:47 -0000	1.49
@@ -53,24 +53,6 @@
  * @{
  */
 
-static void
-init_guid (DBusGUID *guid)
-{
-  long now;
-  char *p;
-  int ts_size;
-
-  _dbus_get_current_time (&now, NULL);
-
-  guid->as_uint32s[0] = now;
-
-  ts_size = sizeof (guid->as_uint32s[0]);
-  p = ((char*)guid->as_bytes) + ts_size;
-  
-  _dbus_generate_random_bytes_buffer (p,
-                                      sizeof (guid->as_bytes) - ts_size);
-}
-
 /* this is a little fragile since it assumes the address doesn't
  * already have a guid, but it shouldn't
  */
@@ -116,8 +98,6 @@
                         const DBusServerVTable *vtable,
                         const DBusString       *address)
 {
-  DBusString guid_raw;
-  
   server->vtable = vtable;
   server->refcount.value = 1;
 
@@ -128,13 +108,9 @@
   if (!_dbus_string_init (&server->guid_hex))
     return FALSE;
 
-  init_guid (&server->guid);
+  _dbus_generate_uuid (&server->guid);
 
-  _dbus_string_init_const_len (&guid_raw, (signed char*) server->guid.as_bytes,
-                               sizeof (server->guid.as_bytes));
-  if (!_dbus_string_hex_encode (&guid_raw, 0,
-                                &server->guid_hex,
-                                _dbus_string_get_length (&server->guid_hex)))
+  if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
     goto failed;
   
   server->address = copy_address_with_guid_appended (address,

Index: dbus-string-private.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string-private.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- dbus-string-private.h	3 Aug 2006 20:34:36 -0000	1.7
+++ dbus-string-private.h	1 Oct 2006 03:18:47 -0000	1.8
@@ -107,6 +107,18 @@
 #define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
   DBUS_GENERIC_STRING_PREAMBLE (real)
 
+/**
+ * Checks for ASCII blank byte
+ * @param c the byte
+ */
+#define DBUS_IS_ASCII_BLANK(c) ((c) == ' ' || (c) == '\t')
+
+/**
+ * Checks for ASCII whitespace byte
+ * @param c the byte
+ */
+#define DBUS_IS_ASCII_WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
+
 /** @} */
 
 DBUS_END_DECLS

Index: dbus-string-util.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string-util.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- dbus-string-util.c	25 Feb 2005 22:03:30 -0000	1.3
+++ dbus-string-util.c	1 Oct 2006 03:18:47 -0000	1.4
@@ -111,43 +111,6 @@
   return i >= 0;
 }
 
-/**
- * Skips whitespace from start, storing the first non-whitespace in *end.
- * (whitespace is space, tab, newline, CR).
- *
- * @param str the string
- * @param start where to start
- * @param end where to store the first non-whitespace byte index
- */
-void
-_dbus_string_skip_white (const DBusString *str,
-                         int               start,
-                         int              *end)
-{
-  int i;
-  DBUS_CONST_STRING_PREAMBLE (str);
-  _dbus_assert (start <= real->len);
-  _dbus_assert (start >= 0);
-  
-  i = start;
-  while (i < real->len)
-    {
-      if (!(real->str[i] == ' ' ||
-            real->str[i] == '\n' ||
-            real->str[i] == '\r' ||
-            real->str[i] == '\t'))
-        break;
-      
-      ++i;
-    }
-
-  _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
-                                    real->str[i] == '\t'));
-  
-  if (end)
-    *end = i;
-}
-
 /** @} */
 
 #ifdef DBUS_BUILD_TESTS

Index: dbus-string.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- dbus-string.c	8 Aug 2006 22:08:39 -0000	1.72
+++ dbus-string.c	1 Oct 2006 03:18:47 -0000	1.73
@@ -1924,21 +1924,85 @@
   i = start;
   while (i < real->len)
     {
-      if (!(real->str[i] == ' ' ||
-            real->str[i] == '\t'))
+      if (!DBUS_IS_ASCII_BLANK (real->str[i]))
         break;
       
       ++i;
     }
 
-  _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
-                                    real->str[i] == '\t'));
+  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
+  
+  if (end)
+    *end = i;
+}
+
+
+/**
+ * Skips whitespace from start, storing the first non-whitespace in *end.
+ * (whitespace is space, tab, newline, CR).
+ *
+ * @param str the string
+ * @param start where to start
+ * @param end where to store the first non-whitespace byte index
+ */
+void
+_dbus_string_skip_white (const DBusString *str,
+                         int               start,
+                         int              *end)
+{
+  int i;
+  DBUS_CONST_STRING_PREAMBLE (str);
+  _dbus_assert (start <= real->len);
+  _dbus_assert (start >= 0);
+  
+  i = start;
+  while (i < real->len)
+    {
+      if (!DBUS_IS_ASCII_WHITE (real->str[i]))
+        break;
+      
+      ++i;
+    }
+
+  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
   
   if (end)
     *end = i;
 }
 
 /**
+ * Skips whitespace from end, storing the start index of the trailing
+ * whitespace in *start. (whitespace is space, tab, newline, CR).
+ *
+ * @param str the string
+ * @param end where to start scanning backward
+ * @param start where to store the start of whitespace chars
+ */
+void
+_dbus_string_skip_white_reverse (const DBusString *str,
+                                 int               end,
+                                 int              *start)
+{
+  int i;
+  DBUS_CONST_STRING_PREAMBLE (str);
+  _dbus_assert (end <= real->len);
+  _dbus_assert (end >= 0);
+  
+  i = end;
+  while (i > 0)
+    {
+      if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
+        break;
+      --i;
+    }
+
+  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
+  
+  if (start)
+    *start = i;
+}
+
+/**
  * Assigns a newline-terminated or \\r\\n-terminated line from the front
  * of the string to the given dest string. The dest string's previous
  * contents are deleted. If the source string contains no newline,
@@ -2043,6 +2107,26 @@
 #endif
 
 /**
+ * Deletes leading and trailing whitespace
+ * 
+ * @param str the string
+ */
+void
+_dbus_string_chop_white(DBusString *str)
+{
+  int i;
+  
+  _dbus_string_skip_white (str, 0, &i);
+
+  if (i > 0)
+    _dbus_string_delete (str, 0, i);
+  
+  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
+
+  _dbus_string_set_length (str, i);
+}
+
+/**
  * Tests two DBusString for equality.
  *
  * @todo memcmp is probably faster

Index: dbus-string.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- dbus-string.h	3 Aug 2006 20:34:36 -0000	1.40
+++ dbus-string.h	1 Oct 2006 03:18:47 -0000	1.41
@@ -233,6 +233,9 @@
 void          _dbus_string_skip_white            (const DBusString  *str,
                                                   int                start,
                                                   int               *end);
+void          _dbus_string_skip_white_reverse    (const DBusString  *str,
+                                                  int                end,
+                                                  int               *start);
 dbus_bool_t   _dbus_string_equal                 (const DBusString  *a,
                                                   const DBusString  *b);
 dbus_bool_t   _dbus_string_equal_c_str           (const DBusString  *a,
@@ -253,6 +256,7 @@
                                                   DBusString        *dest);
 void          _dbus_string_delete_first_word     (DBusString        *str);
 void          _dbus_string_delete_leading_blanks (DBusString        *str);
+void          _dbus_string_chop_white            (DBusString        *str); 
 dbus_bool_t   _dbus_string_append_byte_as_hex    (DBusString        *str,
                                                   int                byte);
 dbus_bool_t   _dbus_string_hex_encode            (const DBusString  *source,

Index: dbus-sysdeps-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-unix.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- dbus-sysdeps-unix.c	30 Sep 2006 19:38:34 -0000	1.6
+++ dbus-sysdeps-unix.c	1 Oct 2006 03:18:47 -0000	1.7
@@ -2297,10 +2297,12 @@
   pid_t pid;
   int ret;
   int status;
-  int orig_len = _dbus_string_get_length (address);
+  int orig_len;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
+  orig_len = _dbus_string_get_length (address);
+  
 #define READ_END        0
 #define WRITE_END       1
   if (pipe (address_pipe) < 0)
@@ -2388,6 +2390,34 @@
   return TRUE;
 }
 
+/**
+ * Reads the uuid of the machine we're running on from
+ * the dbus configuration. Optionally try to create it
+ * (only root can do this usually).
+ *
+ * On UNIX, reads a file that gets created by dbus-uuidgen
+ * in a post-install script. On Windows, if there's a standard
+ * machine uuid we could just use that, but I can't find one
+ * with the right properties (the hardware profile guid can change
+ * without rebooting I believe). If there's no standard one
+ * we might want to use the registry instead of a file for
+ * this, and I'm not sure how we'd ensure the uuid gets created.
+ *
+ * @param guid to init with the machine's uuid
+ * @param create_if_not_found try to create the uuid if it doesn't exist
+ * @param error the error return
+ * @returns #FALSE if the error is set
+ */
+dbus_bool_t
+_dbus_read_local_machine_uuid (DBusGUID   *machine_id,
+                               dbus_bool_t create_if_not_found,
+                               DBusError  *error)
+{
+  DBusString filename;
+  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
+  return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
+}
+
 /** @} end of sysdeps */
 
 /* tests in dbus-sysdeps-util.c */

Index: dbus-sysdeps.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.c,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -d -r1.113 -r1.114
--- dbus-sysdeps.c	11 Sep 2006 17:41:21 -0000	1.113
+++ dbus-sysdeps.c	1 Oct 2006 03:18:47 -0000	1.114
@@ -919,7 +919,7 @@
 #endif
 #ifdef EEXIST
     case EEXIST:
-      return DBUS_ERROR_FILE_NOT_FOUND;
+      return DBUS_ERROR_FILE_EXISTS;
 #endif
 #ifdef ENOENT
     case ENOENT:

Index: dbus-sysdeps.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.h,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- dbus-sysdeps.h	30 Sep 2006 19:38:34 -0000	1.60
+++ dbus-sysdeps.h	1 Oct 2006 03:18:47 -0000	1.61
@@ -379,6 +379,13 @@
 dbus_bool_t _dbus_get_autolaunch_address (DBusString *address, 
 					  DBusError *error);
 
+typedef union DBusGUID DBusGUID;
+
+dbus_bool_t _dbus_read_local_machine_uuid   (DBusGUID         *machine_id,
+                                             dbus_bool_t       create_if_not_found,
+                                             DBusError        *error);
+
+
 DBUS_END_DECLS
 
 #endif /* DBUS_SYSDEPS_H */

Index: dbus-threads.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- dbus-threads.c	14 Sep 2006 04:26:00 -0000	1.29
+++ dbus-threads.c	1 Oct 2006 03:18:47 -0000	1.30
@@ -450,7 +450,8 @@
     LOCK_ADDR (shutdown_funcs),
     LOCK_ADDR (system_users),
     LOCK_ADDR (message_cache),
-    LOCK_ADDR (shared_connections)
+    LOCK_ADDR (shared_connections),
+    LOCK_ADDR (machine_uuid)
 #undef LOCK_ADDR
   };
 

--- NEW FILE: dbus-uuidgen.c ---
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-uuidgen.c  The guts of the dbus-uuidgen binary live in libdbus, in this file.
 *
 * Copyright (C) 2006  Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#include "dbus-uuidgen.h"
#include "dbus-internals.h"
#include "dbus-string.h"
#include "dbus-protocol.h"

#ifdef DBUS_WIN
#error "dbus-uuidgen should not be needed on Windows"
#endif

/**
 * @defgroup DBusInternalsUuidgen dbus-uuidgen implementation
 * @ingroup DBusInternals
 * @brief Functions for dbus-uuidgen binary
 *
 * These are not considered part of the ABI, and if you call them
 * you will get screwed by future changes.
 * 
 * @{
 */

static dbus_bool_t
return_uuid (DBusGUID   *uuid,
             char      **uuid_p,
             DBusError  *error)
{
  if (uuid_p)
    {
      DBusString encoded;
      _dbus_string_init (&encoded);
      if (!_dbus_uuid_encode (uuid, &encoded) ||
          !_dbus_string_steal_data (&encoded, uuid_p))
        {
          _DBUS_SET_OOM (error);
          _dbus_string_free (&encoded);
          return FALSE;
        }
      _dbus_string_free (&encoded);
    }
  return TRUE;
}

/**
 * For use by the dbus-uuidgen binary ONLY, do not call this.
 * We can and will change this function without modifying
 * the libdbus soname.
 *
 * @param filename the file or #NULL for the machine ID file
 * @param uuid_p out param to return the uuid
 * @param create_if_not_found whether to create it if not already there
 * @param error error return
 * @param returns #FALSE if error is set
 */
dbus_bool_t
dbus_internal_do_not_use_get_uuid (const char *filename,
                                   char      **uuid_p,
                                   dbus_bool_t create_if_not_found,
                                   DBusError  *error)
{
  DBusGUID uuid;
  
  if (filename)
    {
      DBusString filename_str;
      _dbus_string_init_const (&filename_str, filename);
      if (!_dbus_read_uuid_file (&filename_str, &uuid, create_if_not_found, error))
        goto error;
    }
  else
    {
      if (!_dbus_read_local_machine_uuid (&uuid, create_if_not_found, error))
        goto error;
    }

  if (!return_uuid(&uuid, uuid_p, error))
    goto error;

  return TRUE;
  
 error:
  _DBUS_ASSERT_ERROR_IS_SET (error);
  return FALSE;
}

/**
 * For use by the dbus-uuidgen binary ONLY, do not call this.
 * We can and will change this function without modifying
 * the libdbus soname.
 *
 * @param uuid_p out param to return the uuid
 * @param returns #FALSE if no memory
 */
dbus_bool_t
dbus_internal_do_not_use_create_uuid (char      **uuid_p)
{
  DBusGUID uuid;

  _dbus_generate_uuid (&uuid);
  return return_uuid (&uuid, uuid_p, NULL);
}

/** @} */

--- NEW FILE: dbus-uuidgen.h ---
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-uuidgen.h  The guts of the dbus-uuidgen binary live in libdbus, in this file.
 *
 * Copyright (C) 2006  Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#ifdef DBUS_INSIDE_DBUS_H
#error "You can't include dbus-uuidgen.h in the public header dbus.h"
#endif

#ifndef DBUS_UUIDGEN_H
#define DBUS_UUIDGEN_H

#include <dbus/dbus-types.h>
#include <dbus/dbus-errors.h>

DBUS_BEGIN_DECLS

dbus_bool_t dbus_internal_do_not_use_get_uuid    (const char *filename,
                                                  char      **uuid_p,
                                                  dbus_bool_t create_if_not_found,
                                                  DBusError  *error);
dbus_bool_t dbus_internal_do_not_use_ensure_uuid (const char *filename,
                                                  char      **uuid_p,
                                                  DBusError  *error);
dbus_bool_t dbus_internal_do_not_use_create_uuid (char      **uuid_p);


DBUS_END_DECLS

#endif /* DBUS_UUIDGEN_H */



More information about the dbus-commit mailing list