[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