[patch] Auto session bus launch from libdbus, take 2

John (J5) Palmieri johnp at redhat.com
Mon Sep 18 14:41:52 PDT 2006


looks good to me

On Sat, 2006-09-16 at 19:06 -0400, Havoc Pennington wrote:
> Hi,
> 
> Here is a patch to add a guaranteed machine uuid on any system that has 
> libdbus installed.
> 
> The only large problem with this dbus-uuidgen is that it uses the static 
> version of libdbus that has the private string, random bytes, etc. 
> utility functions exported, so the executable is a couple hundred K for 
> no good reason.
> 
> Not committing this yet since I'm not sure how it interacts with 1.0, 
> plus it could use some review.
> 
> Unrelated, I realized that on an embedded system someone could make 
> dbus-daemon use the shared libdbus by removing the 
> private-symbol-stripping - that would give 100K or so of disk savings.
> Just in case any list lurkers could use that space ;-)
> 
> Havoc
> 
> plain text document attachment (uuidgen.patch)
> Index: ChangeLog
> ===================================================================
> RCS file: /cvs/dbus/dbus/ChangeLog,v
> retrieving revision 1.1127
> diff -u -p -r1.1127 ChangeLog
> --- ChangeLog	16 Sep 2006 19:24:07 -0000	1.1127
> +++ ChangeLog	16 Sep 2006 22:59:46 -0000
> @@ -1,5 +1,11 @@
>  2006-09-16  Havoc Pennington  <hp at redhat.com>
>  
> +	* tools/dbus-uuidgen.c: add a machine uuid generator command,
> +	which can go in postinstall scripts and ensure we have a unique
> +	machine id on any system running dbus.
> +
> +2006-09-16  Havoc Pennington  <hp at redhat.com>
> +
>  	* dbus/dbus-transport.c (_dbus_transport_open): modify to delegate
>  	to _dbus_transport_open_platform_specific,
>  	_dbus_transport_open_socket,
> Index: tools/Makefile.am
> ===================================================================
> RCS file: /cvs/dbus/dbus/tools/Makefile.am,v
> retrieving revision 1.20
> diff -u -p -r1.20 Makefile.am
> --- tools/Makefile.am	8 Aug 2006 21:30:31 -0000	1.20
> +++ tools/Makefile.am	16 Sep 2006 22:59:47 -0000
> @@ -1,6 +1,6 @@
> -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\"
> +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\" -DDBUS_CONFIG_DIR=\""$(sysconfdir)/dbus-1"\"
>  
> -bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets
> +bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets dbus-uuidgen
>  
>  dbus_send_SOURCES=				\
>  	dbus-print-message.c			\
> @@ -18,11 +18,15 @@ dbus_launch_SOURCES=				\
>  dbus_cleanup_sockets_SOURCES=			\
>  	dbus-cleanup-sockets.c
>  
> +dbus_uuidgen_SOURCES=				\
> +	dbus-uuidgen.c
> +
>  dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la
>  dbus_monitor_LDADD= $(top_builddir)/dbus/libdbus-1.la
> +dbus_uuidgen_LDADD= $(top_builddir)/dbus/libdbus-convenience.la
>  dbus_launch_LDADD= $(DBUS_X_LIBS)
>  
> -man_MANS = dbus-send.1 dbus-monitor.1 dbus-launch.1 dbus-cleanup-sockets.1
> +man_MANS = dbus-send.1 dbus-monitor.1 dbus-launch.1 dbus-cleanup-sockets.1 dbus-uuidgen.1
>  EXTRA_DIST = $(man_MANS) run-with-tmp-session-bus.sh
>  CLEANFILES = 				\
>  	run-with-tmp-session-bus.conf
> Index: tools/dbus-cleanup-sockets.1
> ===================================================================
> RCS file: /cvs/dbus/dbus/tools/dbus-cleanup-sockets.1,v
> retrieving revision 1.2
> diff -u -p -r1.2 dbus-cleanup-sockets.1
> --- tools/dbus-cleanup-sockets.1	3 Aug 2006 20:34:36 -0000	1.2
> +++ tools/dbus-cleanup-sockets.1	16 Sep 2006 22:59:47 -0000
> @@ -11,8 +11,8 @@ dbus-cleanup-sockets \- clean up leftove
>  
>  .SH DESCRIPTION
>  
> -The \fIdbus-cleanup-sockets\fP command cleans up sockets used for
> -D-Bus connections. See http://www.freedesktop.org/software/dbus/ for
> +The \fIdbus-cleanup-sockets\fP command cleans up unused D-Bus
> +connection sockets. See http://www.freedesktop.org/software/dbus/ for
>  more information about the big picture.
>  
>  .PP
> @@ -21,6 +21,19 @@ in the standard default socket directory
>  per-user-login-session message bus; this is usually /tmp. 
>  Optionally, you can pass a different directory on the command line.
>  
> +.PP
> +On Linux, this program is essentially useless, because D-Bus defaults
> +to using "abstract sockets" that exist only in memory and don't have a
> +corresponding file in /tmp. 
> +
> +.PP
> +On most other flavors of UNIX, it's possible for the socket files to
> +leak when programs using D-Bus exit abnormally or without closing
> +their D-Bus connections. Thus, it might be interesting to run
> +dbus-cleanup-sockets in a cron job to mop up any leaked sockets.
> +Or you can just ignore the leaked sockets, they aren't really hurting
> +anything, other than cluttering the output of "ls /tmp"
> +
>  .SH AUTHOR
>  dbus-cleanup-sockets was adapted by Havoc Pennington from
>  linc-cleanup-sockets written by Michael Meeks.
> Index: tools/dbus-uuidgen.1
> ===================================================================
> RCS file: tools/dbus-uuidgen.1
> diff -N tools/dbus-uuidgen.1
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tools/dbus-uuidgen.1	16 Sep 2006 22:59:47 -0000
> @@ -0,0 +1,62 @@
> +.\" 
> +.\" dbus-uuidgen manual page.
> +.\" Copyright (C) 2006 Red Hat, Inc.
> +.\"
> +.TH dbus-uuidgen 1
> +.SH NAME
> +dbus-uuidgen \- Utility to generate UUIDs
> +.SH SYNOPSIS
> +.PP
> +.B dbus-uuidgen [\-\-version] [\-\-ensure[=FILENAME]] [\-\-get[=FILENAME]]
> +
> +.SH DESCRIPTION
> +
> +The \fIdbus-uuidgen\fP command generates a universally unique ID. It
> +is similar to the "uuidgen" command found on many systems already, but 
> +D-Bus can't rely on that command existing everywhere.
> +
> +.PP
> +See http://www.freedesktop.org/software/dbus/ for more information
> +about D-Bus.
> +
> +.PP
> +The primary usage of \fIdbus-uuidgen\fP is to run in the post-install
> +script of a D-Bus package with the "--ensure" option. This 
> +will ensure that /etc/dbus-1/machine-id (or
> +a specified file) exists and has the uuid in it.
> +It won't overwrite an existing uuid, since this id should remain fixed
> +for a single machine.
> +
> +.PP
> +If you run the command with no options it just prints a new uuid.
> +
> +.PP
> +If you run it with --get, it prints the machine uuid by default, or
> +the uuid in the specified file if you specify a file.
> +
> +.SH OPTIONS
> +The following options are supported:
> +.TP
> +.I "--get[=FILENAME]"
> +If a filename is not given, defaults to sysconfdir/dbus-1/machine-id
> +(sysconfdir is usually /etc). If this file exists and is valid, the
> +uuid in the file is printed on stdout. Otherwise, the command exits 
> +with a nonzero status.
> +
> +.TP
> +.I "--ensure[=FILENAME]"
> +If a filename is not given, defaults to sysconfdir/dbus-1/machine-id
> +(sysconfdir is usually /etc). If this file exists then it will be
> +validated, and a failure code returned if it contains the wrong thing.
> +If the file does not exist, it will be created with a new uuid in it.
> +
> +.TP
> +.I "--version"
> +Print the version of dbus-uuidgen
> +
> +.SH AUTHOR
> +See http://www.freedesktop.org/software/dbus/doc/AUTHORS
> +
> +.SH BUGS
> +Please send bug reports to the D-Bus mailing list or bug tracker,
> +see http://www.freedesktop.org/software/dbus/
> Index: tools/dbus-uuidgen.c
> ===================================================================
> RCS file: tools/dbus-uuidgen.c
> diff -N tools/dbus-uuidgen.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tools/dbus-uuidgen.c	16 Sep 2006 22:59:47 -0000
> @@ -0,0 +1,269 @@
> +/* -*- mode: C; c-file-style: "gnu" -*- */
> +/* dbus-uuidgen.c  Utility program to create UUIDs
> + *
> + * Copyright (C) 2006 Red Hat, Inc.
> + *
> + * 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 <config.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <dbus/dbus-sysdeps.h>
> +#include <dbus/dbus-string.h>
> +
> +static void
> +delete_leading_whitespace (DBusString *str)
> +{
> +  int i;
> +  
> +  _dbus_string_skip_white (str, 0, &i);
> +
> +  if (i > 0)
> +    _dbus_string_delete (str, 0, i);
> +}
> +
> +static void
> +usage (char *name, int ecode)
> +{
> +  if (name == NULL)
> +    name = "dbus-uuidgen";
> +  
> +  fprintf (stderr, "Usage: %s [--ensure[=FILENAME]] [--get[=FILENAME]]\n", name);
> +  exit (ecode);
> +}
> +
> +static void
> +version (void)
> +{
> +  printf ("D-Bus UUID Generator %s\n"
> +          "Copyright (C) 2006 Red Hat, Inc.\n"
> +          "This is free software; see the source for copying conditions.\n"
> +          "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
> +          VERSION);
> +  exit (0);
> +}
> +
> +/* should not modify str if it returns false */
> +static dbus_bool_t
> +get_arg(const char *arg,
> +        const char *option,
> +        DBusString *str)
> +{
> +  const char *fn;
> +
> +  if (strlen(arg) < strlen(option))
> +    return FALSE;
> +  
> +  fn = arg + strlen(option);
> +
> +  if (!(*fn == '=' || *fn == ' ' || *fn == '\0'))
> +    {
> +      usage (NULL, 1);
> +    }
> +  
> +  if (*fn == '=')
> +    ++fn;
> +  
> +  while (*fn == ' ' && *fn != '\0')
> +    ++fn;
> +  
> +  if (*fn != '\0')
> +    {
> +      _dbus_string_init_const (str, fn);
> +      return TRUE;
> +    }
> +
> +  return FALSE;
> +}
> +
> +int
> +main (int argc, char *argv[])
> +{
> +  int i;
> +  DBusString filename;
> +  DBusString contents;
> +  dbus_bool_t ensure_uuid;
> +  dbus_bool_t get_uuid;
> +
> +  ensure_uuid = FALSE;
> +  get_uuid = FALSE;
> +  
> +  _dbus_string_init_const (&filename, DBUS_CONFIG_DIR "/machine-id");
> +
> +  for (i = 1; i < argc; i++)
> +    {
> +      char *arg = argv[i];
> +
> +      if (strncmp (arg, "--ensure", strlen("--ensure")) == 0)
> +        {
> +          get_arg (arg, "--ensure", &filename);
> +          ensure_uuid = TRUE;
> +        }
> +      else if (strncmp (arg, "--get", strlen("--get")) == 0)
> +        {
> +          get_arg (arg, "--get", &filename);
> +          get_uuid = TRUE;
> +        }
> +      else if (strcmp (arg, "--help") == 0)
> +	usage (argv[0], 0);
> +      else if (strcmp (arg, "--version") == 0)
> +        version ();
> +      else
> +        usage (argv[0], 1);
> +    }
> +
> +  if (get_uuid && ensure_uuid)
> +    {
> +      fprintf (stderr, "Can't specify both --get-for-machine and --ensure-for-machine\n");
> +      exit (1);
> +    }
> +  
> +  /* Don't cut-and-paste this string code as an example, none of it
> +   * checks for out of memory or frees anything.
> +   */
> +  
> +  _dbus_string_init (&contents);
> +  if ((get_uuid || ensure_uuid) && _dbus_file_get_contents (&contents, &filename, NULL))
> +    {
> +
> +      /* If the file exists and is valid we exit successfully;
> +       * if it exists but contains junk, we don't overwrite
> +       * it (don't want to lose data) but we also exit with
> +       * a failure code.
> +       */
> +      
> +      DBusString decoded;
> +      int end;
> +      
> +      delete_leading_whitespace (&contents);
> +      _dbus_string_init (&decoded);
> +
> +      /* this function will allow the last hex pair to be just one
> +       * character instead of 2, so it isn't 100% as strict as
> +       * it should be for this.
> +       */
> +      _dbus_string_hex_decode (&contents, 0, &end, &decoded, 0);
> +
> +      if (end == 0)
> +        {
> +          fprintf (stderr, "File '%s' contains something other than a valid hex-encoded uuid\n",
> +                   _dbus_string_get_const_data (&filename));
> +          exit (1);
> +        }
> +      
> +      _dbus_string_delete (&contents, 0, end);
> +      delete_leading_whitespace (&contents);
> +      
> +      if (_dbus_string_get_length (&contents) > 0)
> +        {
> +          fprintf (stderr, "File '%s' contains trailing stuff that is not a valid hex-encoded uuid: '%s'\n",
> +                   _dbus_string_get_const_data (&filename),
> +                   _dbus_string_get_const_data (&contents));
> +          exit (1);
> +        }
> +
> +      if (_dbus_string_get_length (&decoded) != 16)
> +        {
> +          fprintf (stderr, "File '%s' contains %d hex-encoded bytes instead of 16\n",
> +                   _dbus_string_get_const_data (&filename),
> +                   _dbus_string_get_length (&decoded));
> +          exit (1);
> +        }
> +
> +      if (get_uuid)
> +        {
> +          DBusString encoded;
> +          _dbus_string_init (&encoded);
> +          _dbus_string_hex_encode (&decoded, 0, &encoded, 0);
> +          
> +          printf ("%s\n", _dbus_string_get_const_data (&encoded));
> +        }
> +      
> +      /* don't bother to free all the strings */
> +      
> +      exit (0);
> +    }
> +  else if (get_uuid)
> +    {
> +      fprintf (stderr, "No valid uuid in file '%s'\n",
> +               _dbus_string_get_const_data (&filename));
> +      exit (1);
> +    }
> +  else
> +    {
> +      DBusString bytes;
> +      DBusString encoded;
> +      DBusError error;
> +      long tv_sec;
> +      union {
> +        dbus_uint32_t number;
> +        unsigned char bytes[4];
> +      } val32;
> +      
> +      _dbus_string_init (&bytes);
> +      _dbus_get_current_time (&tv_sec, NULL);
> +      val32.number = tv_sec;
> +  
> +      _dbus_string_append_4_aligned (&bytes, val32.bytes);
> +  
> +      if (!_dbus_generate_random_bytes (&bytes, 12))
> +        {
> +          fprintf (stderr, "Failed to generate random bytes for uuid");
> +          exit (1);
> +        }
> +
> +      _dbus_string_init (&encoded);
> +
> +      _dbus_string_hex_encode (&bytes, 0, &encoded, 0);
> +
> +      if (ensure_uuid)
> +        {
> +          /* FIXME this is racy; we need a save_file_exclusively
> +           * function. But in practice this should be fine.
> +           *
> +           * - 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()
> +           */
> +          dbus_error_init (&error);
> +          if (!_dbus_create_file_exclusively (&filename, &error))
> +            {
> +              fprintf (stderr, "Could not create uuid file '%s': %s\n",
> +                       _dbus_string_get_const_data (&filename),
> +                       error.message);
> +              exit (1);
> +            }
> +
> +          if (!_dbus_string_save_to_file (&encoded, &filename, &error))
> +            {
> +              fprintf (stderr, "Failed to save new uuid to '%s': %s\n",
> +                       _dbus_string_get_const_data (&filename),
> +                       error.message);
> +              exit (1);
> +            }
> +        }
> +      else
> +        {
> +          printf ("%s\n",
> +                  _dbus_string_get_const_data (&encoded));
> +        }
> +      
> +      exit (0);
> +    }
> +}
> _______________________________________________
> dbus mailing list
> dbus at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dbus



More information about the dbus mailing list