autolaunch uuid support

Havoc Pennington hp at redhat.com
Sun Oct 1 13:07:29 PDT 2006


Hi,

Just added this patch, it probably breaks something, so please review.

Havoc
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /cvs/dbus/dbus/ChangeLog,v
retrieving revision 1.1135
diff -u -p -r1.1135 ChangeLog
--- ChangeLog	1 Oct 2006 17:21:03 -0000	1.1135
+++ ChangeLog	1 Oct 2006 20:04:06 -0000
@@ -1,5 +1,34 @@
 2006-10-01  Havoc Pennington  <hp at redhat.com>
 
+	* tools/dbus-launch.c (print_variables): if no syntax is given,
+	don't print something that's sort-of-half-sh-syntax, just print
+	a plain key-value pairs thing.
+
+	* tools/dbus-launch-x11.c: use machine ID rather than hostname for
+	the local machine representation (but still have the hostname in
+	the display). Remove the hostname from the display if it is
+	localhost. Change session files to be named
+	~/.dbus/session-bus/machine-display. Change X atoms to be
+	underscore-prefixed so nobody whines about ICCCM compliance.
+	Otherwise name them the same as the env variables.
+	Change session file format to include key-value pairs and an
+	explanatory comment. Keys are the same as the env variables.
+	(set_address_in_x11): X property format can't depend on
+	sizeof(pid_t) on a particular machine, fix to always be 32 bits
+
+	* tools/dbus-launch.c: make --autolaunch take a machine id
+	argument. If --autolaunch is used with a program to run, complain
+	for now (but add a FIXME). Also, don't look for existing bus if 
+	there's a program to run (but add a FIXME).
+
+	* dbus/dbus-sysdeps-unix.c (_dbus_get_autolaunch_address): pass
+	machine uuid to dbus-launch (avoids linking dbus-launch to libdbus
+	just to get this, and avoids duplicating uuid-reading code).
+
+	* tools/dbus-launch.1: clarify various things
+	
+2006-10-01  Havoc Pennington  <hp at redhat.com>
+
 	* test/test-service.c (path_message_func): remove broken extra
 	unref that was hidden by the bugs in dbus-connection.c/dbus-bus.c
 
Index: dbus/dbus-sysdeps-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-unix.c,v
retrieving revision 1.8
diff -u -p -r1.8 dbus-sysdeps-unix.c
--- dbus/dbus-sysdeps-unix.c	1 Oct 2006 15:36:18 -0000	1.8
+++ dbus/dbus-sysdeps-unix.c	1 Oct 2006 20:04:07 -0000
@@ -2293,18 +2293,44 @@ _dbus_get_tmpdir(void)
  * @returns #TRUE on success, #FALSE if an error happened
  */
 dbus_bool_t
-_dbus_get_autolaunch_address (DBusString *address, DBusError *error)
+_dbus_get_autolaunch_address (DBusString *address,
+                              DBusError  *error)
 {
-  static char *argv[] = { DBUS_BINDIR "/dbus-launch", "--autolaunch",
-                          "--binary-syntax", NULL };
+  static char *argv[5];
   int address_pipe[2];
   pid_t pid;
   int ret;
   int status;
   int orig_len;
-
+  int i;
+  DBusString uuid;
+  dbus_bool_t retval;
+  
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  retval = FALSE;
 
+  _dbus_string_init (&uuid);
+  
+  if (!_dbus_get_local_machine_uuid_encoded (&uuid))
+    {
+      _DBUS_SET_OOM (error);
+      goto out;
+    }
+  
+  i = 0;
+  argv[i] = DBUS_BINDIR "/dbus-launch";
+  ++i;
+  argv[i] = "--autolaunch";
+  ++i;
+  argv[i] = _dbus_string_get_const_data (&uuid);
+  ++i;
+  argv[i] = "--binary-syntax";
+  ++i;
+  argv[i] = NULL;
+  ++i;
+
+  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
+  
   orig_len = _dbus_string_get_length (address);
   
 #define READ_END        0
@@ -2316,7 +2342,7 @@ _dbus_get_autolaunch_address (DBusString
                       _dbus_strerror (errno));
       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
                      _dbus_strerror (errno));
-      return FALSE;
+      goto out;
     }
 
   pid = fork ();
@@ -2327,7 +2353,7 @@ _dbus_get_autolaunch_address (DBusString
                       _dbus_strerror (errno));
       _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
                      _dbus_strerror (errno));
-      return FALSE;
+      goto out;
     }
 
   if (pid == 0)
@@ -2389,9 +2415,19 @@ _dbus_get_autolaunch_address (DBusString
       _dbus_string_set_length (address, orig_len);
       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
                       "Failed to execute dbus-launch to autolaunch D-Bus session");
-      return FALSE;
+      goto out;
     }
-  return TRUE;
+
+  retval = TRUE;
+  
+ out:
+  if (retval)
+    _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  else
+    _DBUS_ASSERT_ERROR_IS_SET (error);
+  
+  _dbus_string_free (&uuid);
+  return retval;
 }
 
 /**
Index: tools/Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/tools/Makefile.am,v
retrieving revision 1.24
diff -u -p -r1.24 Makefile.am
--- tools/Makefile.am	1 Oct 2006 15:36:19 -0000	1.24
+++ tools/Makefile.am	1 Oct 2006 20:04:08 -0000
@@ -1,4 +1,6 @@
-INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\"
+configdir=$(sysconfdir)/dbus-1
+
+INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\" -DDBUS_MACHINE_UUID_FILE=\""$(configdir)/machine-id"\"
 
 bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets dbus-uuidgen
 
Index: tools/dbus-launch-x11.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-launch-x11.c,v
retrieving revision 1.2
diff -u -p -r1.2 dbus-launch-x11.c
--- tools/dbus-launch-x11.c	1 Oct 2006 03:18:47 -0000	1.2
+++ tools/dbus-launch-x11.c	1 Oct 2006 20:04:08 -0000
@@ -24,6 +24,8 @@
 
 #ifdef DBUS_BUILD_X11
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -46,39 +48,53 @@ x_io_error_handler (Display *xdisplay)
   return 0;
 }
 
-static char *
-get_local_hostname (void)
+static void
+remove_prefix (char *s,
+               char *prefix)
 {
-  static const int increment = 128;
-  static char *cache = NULL;
-  char *buffer = NULL;
-  int size = 0;
+  int plen;
+
+  plen = strlen (prefix);
 
-  while (cache == NULL)
+  if (strncmp (s, prefix, plen) == 0)
     {
-      size += increment;
-      buffer = realloc (buffer, size);
-      if (buffer == NULL)
-        return NULL;            /* out of memory */
+      memmove (s, s + plen, strlen (s) - plen + 1);
+    }
+}
 
-      if (gethostname (buffer, size - 1) == -1 &&
-          errno != ENAMETOOLONG)
-        return NULL;
+static const char*
+get_homedir (void)
+{
+  const char *home;
+  
+  home = getenv ("HOME");
+  if (home == NULL)
+    {
+      /* try from the user database */
+      struct passwd *user = getpwuid (getuid());
+      if (user != NULL)
+        home = user->pw_dir;
+    }
 
-      buffer[size - 1] = '\0';  /* to make sure */
-      cache = buffer;
+  if (home == NULL)
+    {
+      fprintf (stderr, "Can't get user home directory\n");
+      exit (1);
     }
 
-  return cache;
+  return home;
 }
 
+#define DBUS_DIR ".dbus"
+#define DBUS_SESSION_BUS_DIR "session-bus"
+
 static char *
 get_session_file (void)
 {
-  static const char prefix[] = "/.dbus-session-file_";
-  char *hostname;
+  static const char prefix[] = "/" DBUS_DIR "/" DBUS_SESSION_BUS_DIR "/";
+  const char *machine;
+  const char *home;
   char *display;
-  char *home;
   char *result;
   char *p;
 
@@ -92,43 +108,46 @@ get_session_file (void)
   /* remove the screen part of the display name */
   p = strrchr (display, ':');
   if (p != NULL)
-    for ( ; *p; ++p)
-      if (*p == '.')
+    {
+      for ( ; *p; ++p)
         {
-          *p = '\0';
-          break;
+          if (*p == '.')
+            {
+              *p = '\0';
+              break;
+            }
         }
+    }
 
-  /* replace the : in the display with _ */
+  /* Note that we leave the hostname in the display most of the
+   * time. The idea is that we want to be per-(machine,display,user)
+   * triplet to be extra-sure we get a bus we can connect to. Ideally
+   * we'd recognize when the hostname matches the machine we're on in
+   * all cases; we do try to drop localhost and localhost.localdomain
+   * as a special common case so that alternate spellings of DISPLAY
+   * don't result in extra bus instances.
+   *
+   * We also kill the ":" if there's nothing in front of it. This
+   * avoids an ugly double underscore in the filename.
+   */
+  remove_prefix (display, "localhost.localdomain:");
+  remove_prefix (display, "localhost:");
+  remove_prefix (display, ":");
+
+  /* replace the : in the display with _ if the : is still there.
+   * use _ instead of - since it can't be in hostnames.
+   */
   for (p = display; *p; ++p)
-    if (*p == ':')
-      *p = '_';
-
-  hostname = get_local_hostname ();
-  if (hostname == NULL)
     {
-      /* out of memory */
-      free (display);
-      return NULL;
+      if (*p == ':')
+        *p = '_';
     }
+  
+  machine = get_machine_uuid ();
 
-  home = getenv ("HOME");
-  if (home == NULL)
-    {
-      /* try from the user database */
-      struct passwd *user = getpwuid (getuid());
-      if (user == NULL)
-        {
-          verbose ("X11 integration disabled because the home directory"
-                   " could not be determined\n");
-          free (display);
-          return NULL;
-        }
-
-      home = user->pw_dir;
-    }
-
-  result = malloc (strlen (home) + strlen (prefix) + strlen (hostname) +
+  home = get_homedir ();
+  
+  result = malloc (strlen (home) + strlen (prefix) + strlen (machine) +
                    strlen (display) + 2);
   if (result == NULL)
     {
@@ -139,8 +158,8 @@ get_session_file (void)
 
   strcpy (result, home);
   strcat (result, prefix);
-  strcat (result, hostname);
-  strcat (result, "_");
+  strcat (result, machine);
+  strcat (result, "-");
   strcat (result, display);
   free (display);
 
@@ -148,6 +167,46 @@ get_session_file (void)
   return result;
 }
 
+static void
+ensure_session_directory (void)
+{
+  const char *home;
+  char *dir;
+  
+  home = get_homedir ();
+
+  /* be sure we have space for / and nul */
+  dir = malloc (strlen (home) + strlen (DBUS_DIR) + strlen (DBUS_SESSION_BUS_DIR) + 3);
+  if (dir == NULL)
+    {
+      fprintf (stderr, "no memory\n");
+      exit (1);
+    }
+  
+  strcpy (dir, home);
+  strcat (dir, "/");
+  strcat (dir, DBUS_DIR);
+
+  if (mkdir (dir, 0700) < 0)
+    {
+      /* only print a warning here, writing the session file itself will fail later */
+      if (errno != EEXIST)
+        fprintf (stderr, "Unable to create %s\n", dir);
+    }
+
+  strcat (dir, "/");
+  strcat (dir, DBUS_SESSION_BUS_DIR);
+
+  if (mkdir (dir, 0700) < 0)
+    {
+      /* only print a warning here, writing the session file itself will fail later */
+      if (errno != EEXIST)
+        fprintf (stderr, "Unable to create %s\n", dir);
+    }
+  
+  free (dir);
+}
+
 static Display *
 open_x11 (void)
 {
@@ -166,12 +225,12 @@ open_x11 (void)
 static int
 init_x_atoms (Display *display)
 {
-  static const char selection_prefix[] = "DBUS_SESSION_SELECTION_";
-  static const char address_prefix[] = "DBUS_SESSION_ADDRESS";
-  static const char pid_prefix[] = "DBUS_SESSION_PID";
+  static const char selection_prefix[] = "_DBUS_SESSION_BUS_SELECTION_";
+  static const char address_prefix[] = "_DBUS_SESSION_BUS_ADDRESS";
+  static const char pid_prefix[] = "_DBUS_SESSION_BUS_PID";
   static int init = FALSE;
   char *atom_name;
-  char *hostname;
+  const char *machine;
   char *user_name;
   struct passwd *user;
 
@@ -186,15 +245,9 @@ init_x_atoms (Display *display)
     }
   user_name = xstrdup(user->pw_name);
 
-  hostname = get_local_hostname ();
-  if (hostname == NULL)
-    {
-      verbose ("Could not create X11 atoms; aborting X11 integration.\n");
-      free (user_name);
-      return FALSE;
-    }
+  machine = get_machine_uuid ();
 
-  atom_name = malloc (strlen (hostname) + strlen (user_name) + 2 +
+  atom_name = malloc (strlen (machine) + strlen (user_name) + 2 +
                       MAX (strlen (selection_prefix),
                            MAX (strlen (address_prefix),
                                 strlen (pid_prefix))));
@@ -209,7 +262,7 @@ init_x_atoms (Display *display)
   strcpy (atom_name, selection_prefix);
   strcat (atom_name, user_name);
   strcat (atom_name, "_");
-  strcat (atom_name, hostname);
+  strcat (atom_name, machine);
   selection_atom = XInternAtom (display, atom_name, FALSE);
 
   /* create the address property atom */
@@ -285,7 +338,8 @@ set_address_in_x11(char *address, pid_t 
 {
   char *current_address;
   Window wid;
-
+  int pid32;
+  
   /* lock the X11 display to make sure we're doing this atomically */
   XGrabServer (xdisplay);
 
@@ -313,8 +367,14 @@ set_address_in_x11(char *address, pid_t 
   /* Save the property in the window */
   XChangeProperty (xdisplay, wid, address_atom, XA_STRING, 8, PropModeReplace,
                    (unsigned char *)address, strlen (address));
+  pid32 = pid;
+  if (sizeof(pid32) != 4)
+    {
+      fprintf (stderr, "int is not 32 bits!\n");
+      exit (1);
+    }
   XChangeProperty (xdisplay, wid, pid_atom, XA_CARDINAL, 32, PropModeReplace,
-                   (unsigned char *)&pid, sizeof(pid) / 4);
+                   (unsigned char *)&pid32, 1);
 
   /* Now grab the selection */
   XSetSelectionOwner (xdisplay, selection_atom, wid, CurrentTime);
@@ -337,6 +397,7 @@ set_address_in_file (char *address, pid_
   char *session_file;
   FILE *f;
 
+  ensure_session_directory ();
   session_file = get_session_file();
   if (session_file == NULL)
     return FALSE;
@@ -344,7 +405,18 @@ set_address_in_file (char *address, pid_
   f = fopen (session_file, "w");
   if (f == NULL)
     return FALSE;               /* some kind of error */
-  fprintf (f, "%s\n%ld\n%ld\n", address, (long)pid, (long)wid);
+  fprintf (f,
+           "# This file allows processes on the machine with id %s using \n"
+           "# display %s to find the D-Bus session bus with the below address.\n"
+           "# If the DBUS_SESSION_BUS_ADDRESS environment variable is set, it will\n"
+           "# be used rather than this file.\n"
+           "# See \"man dbus-launch\" for more details.\n"
+           "DBUS_SESSION_BUS_ADDRESS=%s\n"
+           "DBUS_SESSION_BUS_PID=%ld\n"
+           "DBUS_SESSION_BUS_WINDOWID=%ld\n",
+           get_machine_uuid (),
+           getenv ("DISPLAY"),
+           address, (long)pid, (long)wid);
 
   fclose (f);
   free (session_file);
Index: tools/dbus-launch.1
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-launch.1,v
retrieving revision 1.7
diff -u -p -r1.7 dbus-launch.1
--- tools/dbus-launch.1	30 Sep 2006 19:38:34 -0000	1.7
+++ tools/dbus-launch.1	1 Oct 2006 20:04:08 -0000
@@ -7,27 +7,36 @@
 dbus-launch \- Utility to start a message bus from a shell script
 .SH SYNOPSIS
 .PP
-.B dbus-launch [\-\-version] [\-\-sh-syntax] [\-\-csh-syntax] [\-\-auto-syntax] [\-\-exit-with-session] [\-\-autolaunch] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
+.B dbus-launch [\-\-version] [\-\-sh-syntax] [\-\-csh-syntax] [\-\-auto-syntax] [\-\-exit-with-session] [\-\-autolaunch=MACHINEID] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
 
 .SH DESCRIPTION
 
-The \fIdbus-launch\fP command is used to start \fIdbus-daemon\fP
-from a shell script. It would normally be called from a user's login
+The \fIdbus-launch\fP command is used to start a session bus 
+instance of \fIdbus-daemon\fP from a shell script.
+It would normally be called from a user's login
 scripts. Unlike the daemon itself, \fIdbus-launch\fP exits, so
 backticks or the $() construct can be used to read information from
 \fIdbus-launch\fP.
 
-With no arguments, \fIdbus-launch\fP will simply print the values of
-DBUS_SESSION_BUS_ADDRESS and DBUS_SESSION_BUS_PID.
+With no arguments, \fIdbus-launch\fP will launch a session bus
+instance and print the address and pid of that instance to standard
+output.
 
 You may specify a program to be run; in this case, \fIdbus-launch\fP
-will then set the appropriate environment variables and execute the
+will launch a session bus instance, set the appropriate environment
+variables so the specified program can find the bus, and then execute the
 specified program, with the specified arguments.  See below for
 examples.
 
-Finally, you may use the \-\-sh-syntax, \-\-csh-syntax, or
-\-\-auto-syntax commands to cause \fIdbus-launch\fP to emit shell code
-to set up the environment.  This is useful in shell scripts.
+If you launch a program, \fIdbus-launch\fP will not print the
+information about the new bus to standard output.
+
+When \fIdbus-launch\fP prints bus information to standard output, by
+default it is in a simple key-value pairs format. However, you may 
+request several alternate syntaxes using the \-\-sh-syntax, \-\-csh-syntax,
+\-\-binary-syntax, or
+\-\-auto-syntax options. Several of these cause \fIdbus-launch\fP to emit shell code
+to set up the environment.
 
 With the \-\-auto-syntax option, \fIdbus-launch\fP looks at the value
 of the SHELL environment variable to determine which shell syntax
@@ -67,12 +76,60 @@ dbus-launch gnome-session
 .fi
 The above would likely be appropriate for ~/.xsession or ~/.Xclients.
 
+.SH AUTOMATIC LAUNCHING
+
+.PP
+If DBUS_SESSION_BUS_ADDRESS is not set for a process that tries to use
+D-Bus, by default the process will attempt to invoke dbus-launch with
+the --autolaunch option to start up a new session bus or find the 
+existing bus address on the X display or in a file in
+~/.dbus/session-bus/
+
+.PP
+Whenever an autolaunch occurs, the application that had to
+start a new bus will be in its own little world; it can effectively
+end up starting a whole new session if it tries to use a lot of 
+bus services. This can be suboptimal or even totally broken, depending
+on the app and what it tries to do.
+
+.PP
+There are two common reasons for autolaunch. One is ssh to a remote
+machine. The ideal fix for that would be forwarding of
+DBUS_SESSION_BUS_ADDRESS in the same way that DISPLAY is forwarded.
+In the meantime, you can edit the session.conf config file to 
+have your session bus listen on TCP, and manually set
+DBUS_SESSION_BUS_ADDRESS, if you like.
+
+.PP
+The second common reason for autolaunch is an su to another user, and
+display of X applications running as the second user on the display
+belonging to the first user. Perhaps the ideal fix in this case
+would be to allow the second user to connect to the session bus of the
+first user, just as they can connect to the first user's display.
+However, a mechanism for that has not been coded.
+
+.PP
+You can always avoid autolaunch by manually setting
+DBUS_SESSION_BUS_ADDRESS. Autolaunch happens because the default
+address if none is set is "autolaunch:", so if any other address is
+set there will be no autolaunch. You can however include autolaunch in
+an explicit session bus address as a fallback, for example
+DBUS_SESSION_BUS_ADDRESS="something:,autolaunch:" - in that case if
+the first address doesn't work, processes will autolaunch. (The bus
+address variable contains a comma-separated list of addresses to try.)
+
 .SH OPTIONS
 The following options are supported:
 .TP
 .I "--auto-syntax"
 Choose \-\-csh-syntax or \-\-sh-syntax based on the SHELL environment variable.
 
+.I "--binary-syntax"
+Write to stdout a nul-terminated bus address, then the bus PID as a
+binary integer of size sizeof(pid_t), then the bus X window ID as a
+binary integer of size sizeof(long). Integers are in the machine's
+byte order, not network byte order or any other canonical byte order.
+
 .TP
 .I "--config-file=FILENAME"
 Pass \-\-config-file=FILENAME to the bus daemon, instead of passing it 
@@ -90,11 +147,12 @@ server. If this process gets a HUP on st
 it kills the message bus daemon.
 
 .TP
-.I "--autolaunch"
+.I "--autolaunch=MACHINEID"
 This option implies that \fIdbus-launch\fP should scan for a
 previously-started session and reuse the values found there. If no
 session is found, it will start a new session. The
 \-\-exit-with-session option is implied if \-\-autolaunch is given.
+This option is used by libdbus, you probably do not want to use it manually.
 
 .TP
 .I "--sh-syntax"
Index: tools/dbus-launch.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-launch.c,v
retrieving revision 1.18
diff -u -p -r1.18 dbus-launch.c
--- tools/dbus-launch.c	1 Oct 2006 03:18:47 -0000	1.18
+++ tools/dbus-launch.c	1 Oct 2006 20:04:09 -0000
@@ -1,7 +1,8 @@
 /* -*- mode: C; c-file-style: "gnu" -*- */
 /* dbus-launch.c  dbus-launch utility
  *
- * Copyright (C) 2003 Red Hat, Inc.
+ * Copyright (C) 2003, 2006 Red Hat, Inc.
+ * Copyright (C) 2006 Thiago Macieira <thiago at kde.org>
  *
  * Licensed under the Academic Free License version 2.1
  * 
@@ -39,6 +40,27 @@
 extern Display *xdisplay;
 #endif
 
+static char* machine_uuid = NULL;
+
+const char*
+get_machine_uuid (void)
+{
+  return machine_uuid;
+}
+
+static void
+save_machine_uuid (const char *uuid_arg)
+{
+  if (strlen (uuid_arg) != 32)
+    {
+      fprintf (stderr, "machine ID '%s' looks like it's the wrong length, should be 32 hex digits",
+               uuid_arg);
+      exit (1);
+    }
+
+  machine_uuid = xstrdup (uuid_arg);
+}
+
 void
 verbose (const char *format,
          ...)
@@ -303,8 +325,9 @@ print_variables (const char *bus_address
       printf ("set DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
       if (bus_wid)
 	printf ("set DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
+      fflush (stdout);
     }
-  else
+  else if (bourne_shell_syntax)
     {
       printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
       if (bourne_shell_syntax)
@@ -312,6 +335,15 @@ print_variables (const char *bus_address
       printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
       if (bus_wid)
 	printf ("DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
+      fflush (stdout);
+    }
+  else
+    {
+      printf ("DBUS_SESSION_BUS_ADDRESS=%s\n", bus_address);
+      printf ("DBUS_SESSION_BUS_PID=%ld\n", (long) bus_pid);
+      if (bus_wid)
+	printf ("DBUS_SESSION_BUS_WINDOWID=%ld\n", (long) bus_wid);
+      fflush (stdout);
     }
 }
 
@@ -614,8 +646,38 @@ main (int argc, char **argv)
         version ();
       else if (strcmp (arg, "--exit-with-session") == 0)
         exit_with_session = TRUE;
+      else if (strstr (arg, "--autolaunch=") == arg)
+        {
+          const char *s;
+
+          if (autolaunch)
+            {
+              fprintf (stderr, "--autolaunch given twice\n");
+              exit (1);
+            }
+          
+          autolaunch = TRUE;
+
+          s = strchr (arg, '=');
+          ++s;
+
+          save_machine_uuid (s);
+        }
+      else if (prev_arg &&
+               strcmp (prev_arg, "--autolaunch") == 0)
+        {
+          if (autolaunch)
+            {
+              fprintf (stderr, "--autolaunch given twice\n");
+              exit (1);
+            }
+          
+          autolaunch = TRUE;
+
+          save_machine_uuid (arg);
+        }
       else if (strcmp (arg, "--autolaunch") == 0)
-	autolaunch = TRUE;
+        ; /* wait for next arg */
       else if (strstr (arg, "--config-file=") == arg)
         {
           const char *file;
@@ -673,7 +735,7 @@ main (int argc, char **argv)
     verbose ("--exit-with-session enabled\n");
 
   if (autolaunch)
-    {
+    {      
 #ifndef DBUS_BUILD_X11
       fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n"
 	       "Cannot continue.\n");
@@ -682,7 +744,23 @@ main (int argc, char **argv)
       char *address;
       pid_t pid;
       long wid;
+      
+      if (get_machine_uuid () == NULL)
+        {
+          fprintf (stderr, "Machine UUID not provided as arg to --autolaunch\n");
+          exit (1);
+        }
 
+      /* FIXME right now autolaunch always does print_variables(), but it should really
+       * exec the child program instead if a child program was specified. For now
+       * we just exit if this conflict arises.
+       */
+      if (runprog)
+        {
+          fprintf (stderr, "Currently --autolaunch does not support running a program\n");
+          exit (1);
+        }
+      
       verbose ("Autolaunch enabled (using X11).\n");
       if (!exit_with_session)
 	{
@@ -703,7 +781,7 @@ main (int argc, char **argv)
 	}
 
       if (address != NULL)
-	{
+	{          
 	  verbose ("dbus-daemon is already running. Returning existing parameters.\n");
 	  print_variables (address, pid, wid, c_shell_syntax,
 			   bourne_shell_syntax, binary_syntax);
@@ -902,7 +980,10 @@ main (int argc, char **argv)
       close (bus_pid_to_launcher_pipe[READ_END]);
 
 #ifdef DBUS_BUILD_X11
-      if (xdisplay != NULL)
+      /* FIXME the runprog == NULL is broken - we need to launch the runprog with the existing bus,
+       * instead of just doing print_variables() if there's an existing bus.
+       */
+      if (xdisplay != NULL && runprog == NULL)
         {
           ret2 = x11_save_address (bus_address, bus_pid, &wid);
           if (ret2 == 0)
Index: tools/dbus-launch.h
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-launch.h,v
retrieving revision 1.1
diff -u -p -r1.1 dbus-launch.h
--- tools/dbus-launch.h	30 Sep 2006 19:38:34 -0000	1.1
+++ tools/dbus-launch.h	1 Oct 2006 20:04:09 -0000
@@ -45,6 +45,8 @@ void verbose (const char *format, ...);
 char *xstrdup (const char *str);
 void kill_bus_and_exit (int exitcode);
 
+const char* get_machine_uuid (void);
+
 #ifdef DBUS_BUILD_X11
 /* defined in dbus-launch-x11.c */
 int x11_init (void);


More information about the dbus mailing list