diff options
| -rw-r--r-- | ChangeLog | 10 | ||||
| -rw-r--r-- | tools/dbus-launch.c | 238 | 
2 files changed, 155 insertions, 93 deletions
| @@ -1,3 +1,13 @@ +2007-11-23  Sjoerd Simons  <sjoerd@luon.net> + +	* tools/dbus-launch.c: let both a normal dbus-launch and an +	autolaunched bus save their parameters in X11 if possible. This makes +	the autolaunch and non-autolaunch behaviour more similar. With the +	exception that on a normal launch there will always be a new session +	bus and not being able to save parameters is not fatal. This also +	enables to launch programs directly with autolaunch (not very usefull +	though). +  2007-10-31  Havoc Pennington  <hp@redhat.com>  	* bus/selinux.c (log_audit_callback): rewrite to use diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 9f4c94ab..894847ea 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -23,6 +23,7 @@   */  #include "dbus-launch.h"  #include <stdlib.h> +#include <ctype.h>  #include <unistd.h>  #include <fcntl.h>  #include <signal.h> @@ -61,6 +62,49 @@ save_machine_uuid (const char *uuid_arg)    machine_uuid = xstrdup (uuid_arg);  } +#define UUID_MAXLEN 40 +/* Read the machine uuid from file if needed. Returns TRUE if machine_uuid is + * set after this function */ +static int +read_machine_uuid_if_needed (void) +{ +  FILE *f; +  char uuid[UUID_MAXLEN]; +  size_t len; +  int ret = FALSE; + +  if (machine_uuid != NULL) +    return TRUE; + +  f = fopen (DBUS_MACHINE_UUID_FILE, "r"); +  if (f == NULL) +    return FALSE; + +  if (fgets (uuid, UUID_MAXLEN, f) == NULL) +    goto out; + +  len = strlen (uuid); +  if (len < 32) +    goto out; + +  /* rstrip the read uuid */ +  while (len > 31 && isspace(uuid[len - 1])) +    len--; + +  if (len != 32) +    goto out; + +  uuid[len] = '\0'; +  machine_uuid = xstrdup (uuid); +  verbose ("UID: %s\n", machine_uuid); +  ret = TRUE; + +out: +  fclose(f); +  return ret; +} + +  void  verbose (const char *format,           ...) @@ -290,19 +334,24 @@ do_waitpid (pid_t pid)  static pid_t bus_pid_to_kill = -1; +static void +kill_bus() +{ +  verbose ("Killing message bus and exiting babysitter\n"); +  kill (bus_pid_to_kill, SIGTERM); +  sleep (3); +  kill (bus_pid_to_kill, SIGKILL); +} +  void  kill_bus_and_exit (int exitcode)  { -  verbose ("Killing message bus and exiting babysitter\n"); -      /* in case these point to any NFS mounts, get rid of them immediately */    close (0);    close (1);    close (2); -  kill (bus_pid_to_kill, SIGTERM); -  sleep (3); -  kill (bus_pid_to_kill, SIGKILL); +  kill_bus();    exit (exitcode);  } @@ -621,6 +670,63 @@ do_close_stderr (void)    close (fd);  } +static void +pass_info (const char *runprog, const char *bus_address, pid_t bus_pid, +           long bus_wid, int c_shell_syntax, int bourne_shell_syntax, +           int binary_syntax, +           int argc, char **argv, int remaining_args) +{ +  if (runprog) +    { +      char *envvar; +      char **args; +      int i; + +      envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + +          strlen (bus_address) + 1); +      args = malloc (sizeof (char *) * ((argc-remaining_args)+2)); + +      if (envvar == NULL || args == NULL) +        goto oom; + +     args[0] = xstrdup (runprog); +      if (!args[0]) +        goto oom; +     for (i = 1; i <= (argc-remaining_args); i++) +      { +        size_t len = strlen (argv[remaining_args+i-1])+1; +        args[i] = malloc (len); +        if (!args[i]) +          goto oom; +        strncpy (args[i], argv[remaining_args+i-1], len); +       } +     args[i] = NULL; + +     strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS="); +     strcat (envvar, bus_address); +     putenv (envvar); + +     execvp (runprog, args); +     fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno)); +     exit (1); +    } +   else +    { +      print_variables (bus_address, bus_pid, bus_wid, c_shell_syntax, +         bourne_shell_syntax, binary_syntax); +    } +  verbose ("dbus-launch exiting\n"); + +  fflush (stdout); +  fflush (stderr); +  close (1); +  close (2); +  exit (0); +oom: +  fprintf (stderr, "Out of memory!"); +  exit (1); +} +  #define READ_END  0  #define WRITE_END 1 @@ -801,16 +907,6 @@ main (int argc, char **argv)            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)  	{ @@ -831,15 +927,20 @@ 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); +	  pass_info (runprog, address, pid, wid, c_shell_syntax, +			   bourne_shell_syntax, binary_syntax, argc, argv, remaining_args);  	  exit (0);  	} +    } +   else if (read_machine_uuid_if_needed()) +    { +      x11_init();  #endif      } +    if (pipe (bus_pid_to_launcher_pipe) < 0 ||        pipe (bus_address_to_launcher_pipe) < 0 ||        pipe (bus_pid_to_babysitter_pipe) < 0) @@ -1052,37 +1153,35 @@ main (int argc, char **argv)        close (bus_pid_to_launcher_pipe[READ_END]);  #ifdef DBUS_BUILD_X11 -      /* 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) +      if (xdisplay != NULL)          { +          verbose("Saving x11 address\n");            ret2 = x11_save_address (bus_address, bus_pid, &wid); -          if (ret2 == 0) +          /* Only get an existing dbus session when autolaunching */ +          if (autolaunch)              { -              /* another window got added. Return its address */ -              char *address; -              pid_t pid; -              long wid; -               -              if (x11_get_address (&address, &pid, &wid) && address != NULL) +              if (ret2 == 0)                  { -                  verbose ("dbus-daemon is already running. Returning existing parameters.\n"); -                  print_variables (address, pid, wid, c_shell_syntax, -                                   bourne_shell_syntax, binary_syntax); -                  free (address); -                   +                  char *address = NULL; +                  /* another window got added. Return its address */                    bus_pid_to_kill = bus_pid; -                  kill_bus_and_exit (0); +                  if (x11_get_address (&address, &bus_pid, &wid) +                       && address != NULL) +                    { +                      verbose ("dbus-daemon is already running. Returning existing parameters.\n"); +                      /* Kill the old bus */ +                      kill_bus(); +                      pass_info (runprog, address, bus_pid, wid, +                         c_shell_syntax, bourne_shell_syntax, binary_syntax, +                         argc, argv, remaining_args); +                    } +                  } +              if (ret2 < 0) +                { +                  fprintf (stderr, "Error saving bus information.\n"); +                  bus_pid_to_kill = bus_pid; +                  kill_bus_and_exit (1);                  } -               -              /* if failed, fall through */ -            } -          if (ret2 <= 0) -            { -              fprintf (stderr, "Error saving bus information.\n"); -              bus_pid_to_kill = bus_pid; -              kill_bus_and_exit (1);              }          }  #endif @@ -1091,56 +1190,9 @@ main (int argc, char **argv)        write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid);        close (bus_pid_to_babysitter_pipe[WRITE_END]); -      if (runprog) -	{ -	  char *envvar; -	  char **args; - -	  envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + strlen (bus_address) + 1); -	  args = malloc (sizeof (char *) * ((argc-remaining_args)+2)); - -	  if (envvar == NULL || args == NULL) -	    goto oom; - -	  args[0] = xstrdup (runprog); -	  if (!args[0]) -	    goto oom; -	  for (i = 1; i <= (argc-remaining_args); i++) -	    { -	      size_t len = strlen (argv[remaining_args+i-1])+1; -	      args[i] = malloc (len); -	      if (!args[i]) -		goto oom; -	      strncpy (args[i], argv[remaining_args+i-1], len); -	    } -	  args[i] = NULL; - -	  strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS="); -	  strcat (envvar, bus_address); -	  putenv (envvar); - -	  execvp (runprog, args); -	  fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno)); -	  exit (1); -	} -      else -	{ -	  print_variables (bus_address, bus_pid, wid, c_shell_syntax, -			   bourne_shell_syntax, binary_syntax); -	} -	   -      verbose ("dbus-launch exiting\n"); +       pass_info (runprog, bus_address, bus_pid, wid, c_shell_syntax, +              bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); +    } -      fflush (stdout); -      fflush (stderr); -      close (1); -      close (2); -       -      exit (0); -    }  -      return 0; - oom: -  fprintf (stderr, "Out of memory!"); -  exit (1);  } | 
