summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2011-01-31 17:37:59 +0000
committerSimon McVittie <smcv@debian.org>2011-01-31 17:37:59 +0000
commit24fbe571516161d48b499d587f9adb3e683dbf88 (patch)
tree7d70909156dcf587d91f693b8e1216eb4e0465e1 /tools
parent9b72896b3730a9fceb961be28bb95762a7b4e9d6 (diff)
downloaddbus-24fbe571516161d48b499d587f9adb3e683dbf88.tar.gz
Imported Upstream version 1.2.24upstream/1.2.24
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am47
-rw-r--r--tools/Makefile.in797
-rw-r--r--tools/dbus-cleanup-sockets.143
-rw-r--r--tools/dbus-cleanup-sockets.c431
-rw-r--r--tools/dbus-launch-x11.c463
-rw-r--r--tools/dbus-launch.1183
-rw-r--r--tools/dbus-launch.c1214
-rw-r--r--tools/dbus-launch.h58
-rw-r--r--tools/dbus-monitor.178
-rw-r--r--tools/dbus-monitor.c354
-rw-r--r--tools/dbus-print-message.c407
-rw-r--r--tools/dbus-print-message.h31
-rw-r--r--tools/dbus-send.195
-rw-r--r--tools/dbus-send.c526
-rw-r--r--tools/dbus-uuidgen.189
-rw-r--r--tools/dbus-uuidgen.c161
-rwxr-xr-xtools/run-with-tmp-session-bus.sh76
17 files changed, 5053 insertions, 0 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000..9fad7a78
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,47 @@
+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=\""$(localstatedir)/lib/dbus/machine-id"\"
+
+bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets dbus-uuidgen
+
+dbus_send_SOURCES= \
+ dbus-print-message.c \
+ dbus-print-message.h \
+ dbus-send.c
+
+dbus_monitor_SOURCES= \
+ dbus-monitor.c \
+ dbus-print-message.c \
+ dbus-print-message.h
+
+dbus_launch_SOURCES= \
+ dbus-launch.c \
+ dbus-launch-x11.c \
+ dbus-launch.h
+
+dbus_cleanup_sockets_SOURCES= \
+ dbus-cleanup-sockets.c
+
+dbus_uuidgen_SOURCES= \
+ dbus-uuidgen.c
+
+dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_send_LDFLAGS=@R_DYNAMIC_LDFLAG@
+
+dbus_monitor_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_monitor_LDFLAGS=@R_DYNAMIC_LDFLAG@
+
+dbus_uuidgen_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_uuidgen_LDFLAGS=@R_DYNAMIC_LDFLAG@
+
+dbus_launch_LDADD= $(DBUS_X_LIBS) $(DBUS_CLIENT_LIBS)
+dbus_launch_LDFLAGS=@R_DYNAMIC_LDFLAG@
+
+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
+
+#create the /var/lib/data directory for dbus-uuidgen
+localstatelibdir = $(localstatedir)/lib/dbus
+localstatelib_DATA =
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 00000000..14d048bc
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,797 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = dbus-send$(EXEEXT) dbus-monitor$(EXEEXT) \
+ dbus-launch$(EXEEXT) dbus-cleanup-sockets$(EXEEXT) \
+ dbus-uuidgen$(EXEEXT)
+subdir = tools
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(localstatelibdir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_dbus_cleanup_sockets_OBJECTS = dbus-cleanup-sockets.$(OBJEXT)
+dbus_cleanup_sockets_OBJECTS = $(am_dbus_cleanup_sockets_OBJECTS)
+dbus_cleanup_sockets_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+am_dbus_launch_OBJECTS = dbus-launch.$(OBJEXT) \
+ dbus-launch-x11.$(OBJEXT)
+dbus_launch_OBJECTS = $(am_dbus_launch_OBJECTS)
+am__DEPENDENCIES_1 =
+dbus_launch_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+dbus_launch_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(dbus_launch_LDFLAGS) $(LDFLAGS) -o $@
+am_dbus_monitor_OBJECTS = dbus-monitor.$(OBJEXT) \
+ dbus-print-message.$(OBJEXT)
+dbus_monitor_OBJECTS = $(am_dbus_monitor_OBJECTS)
+dbus_monitor_DEPENDENCIES = $(top_builddir)/dbus/libdbus-1.la \
+ $(am__DEPENDENCIES_1)
+dbus_monitor_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(dbus_monitor_LDFLAGS) $(LDFLAGS) -o $@
+am_dbus_send_OBJECTS = dbus-print-message.$(OBJEXT) \
+ dbus-send.$(OBJEXT)
+dbus_send_OBJECTS = $(am_dbus_send_OBJECTS)
+dbus_send_DEPENDENCIES = $(top_builddir)/dbus/libdbus-1.la \
+ $(am__DEPENDENCIES_1)
+dbus_send_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(dbus_send_LDFLAGS) $(LDFLAGS) -o $@
+am_dbus_uuidgen_OBJECTS = dbus-uuidgen.$(OBJEXT)
+dbus_uuidgen_OBJECTS = $(am_dbus_uuidgen_OBJECTS)
+dbus_uuidgen_DEPENDENCIES = $(top_builddir)/dbus/libdbus-1.la \
+ $(am__DEPENDENCIES_1)
+dbus_uuidgen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(dbus_uuidgen_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(dbus_cleanup_sockets_SOURCES) $(dbus_launch_SOURCES) \
+ $(dbus_monitor_SOURCES) $(dbus_send_SOURCES) \
+ $(dbus_uuidgen_SOURCES)
+DIST_SOURCES = $(dbus_cleanup_sockets_SOURCES) $(dbus_launch_SOURCES) \
+ $(dbus_monitor_SOURCES) $(dbus_send_SOURCES) \
+ $(dbus_uuidgen_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(localstatelib_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_BINDIR = @DBUS_BINDIR@
+DBUS_BUS_CFLAGS = @DBUS_BUS_CFLAGS@
+DBUS_BUS_LIBS = @DBUS_BUS_LIBS@
+DBUS_CLIENT_CFLAGS = @DBUS_CLIENT_CFLAGS@
+DBUS_CLIENT_LIBS = @DBUS_CLIENT_LIBS@
+DBUS_CONSOLE_AUTH_DIR = @DBUS_CONSOLE_AUTH_DIR@
+DBUS_CONSOLE_OWNER_FILE = @DBUS_CONSOLE_OWNER_FILE@
+DBUS_DAEMONDIR = @DBUS_DAEMONDIR@
+DBUS_DATADIR = @DBUS_DATADIR@
+DBUS_HAVE_INT64 = @DBUS_HAVE_INT64@
+DBUS_INT16_TYPE = @DBUS_INT16_TYPE@
+DBUS_INT32_TYPE = @DBUS_INT32_TYPE@
+DBUS_INT64_CONSTANT = @DBUS_INT64_CONSTANT@
+DBUS_INT64_TYPE = @DBUS_INT64_TYPE@
+DBUS_LAUNCHER_CFLAGS = @DBUS_LAUNCHER_CFLAGS@
+DBUS_LAUNCHER_LIBS = @DBUS_LAUNCHER_LIBS@
+DBUS_LIBEXECDIR = @DBUS_LIBEXECDIR@
+DBUS_MAJOR_VERSION = @DBUS_MAJOR_VERSION@
+DBUS_MICRO_VERSION = @DBUS_MICRO_VERSION@
+DBUS_MINOR_VERSION = @DBUS_MINOR_VERSION@
+DBUS_PATH_OR_ABSTRACT = @DBUS_PATH_OR_ABSTRACT@
+DBUS_SESSION_SOCKET_DIR = @DBUS_SESSION_SOCKET_DIR@
+DBUS_SYSTEM_BUS_DEFAULT_ADDRESS = @DBUS_SYSTEM_BUS_DEFAULT_ADDRESS@
+DBUS_SYSTEM_PID_FILE = @DBUS_SYSTEM_PID_FILE@
+DBUS_SYSTEM_SOCKET = @DBUS_SYSTEM_SOCKET@
+DBUS_TEST_CFLAGS = @DBUS_TEST_CFLAGS@
+DBUS_TEST_LIBS = @DBUS_TEST_LIBS@
+DBUS_UINT64_CONSTANT = @DBUS_UINT64_CONSTANT@
+DBUS_USER = @DBUS_USER@
+DBUS_VERSION = @DBUS_VERSION@
+DBUS_X_CFLAGS = @DBUS_X_CFLAGS@
+DBUS_X_LIBS = @DBUS_X_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXPANDED_BINDIR = @EXPANDED_BINDIR@
+EXPANDED_DATADIR = @EXPANDED_DATADIR@
+EXPANDED_LIBDIR = @EXPANDED_LIBDIR@
+EXPANDED_LIBEXECDIR = @EXPANDED_LIBEXECDIR@
+EXPANDED_LOCALSTATEDIR = @EXPANDED_LOCALSTATEDIR@
+EXPANDED_SYSCONFDIR = @EXPANDED_SYSCONFDIR@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBXML_CFLAGS = @LIBXML_CFLAGS@
+LIBXML_LIBS = @LIBXML_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIC_CFLAGS = @PIC_CFLAGS@
+PIC_LDFLAGS = @PIC_LDFLAGS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+R_DYNAMIC_LDFLAG = @R_DYNAMIC_LDFLAG@
+SECTION_FLAGS = @SECTION_FLAGS@
+SECTION_LDFLAGS = @SECTION_LDFLAGS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEST_BUS_BINARY = @TEST_BUS_BINARY@
+TEST_EXIT_BINARY = @TEST_EXIT_BINARY@
+TEST_INVALID_SERVICE_DIR = @TEST_INVALID_SERVICE_DIR@
+TEST_INVALID_SERVICE_SYSTEM_DIR = @TEST_INVALID_SERVICE_SYSTEM_DIR@
+TEST_LAUNCH_HELPER_BINARY = @TEST_LAUNCH_HELPER_BINARY@
+TEST_PRIVSERVER_BINARY = @TEST_PRIVSERVER_BINARY@
+TEST_SEGFAULT_BINARY = @TEST_SEGFAULT_BINARY@
+TEST_SERVICE_BINARY = @TEST_SERVICE_BINARY@
+TEST_SHELL_SERVICE_BINARY = @TEST_SHELL_SERVICE_BINARY@
+TEST_SLEEP_FOREVER_BINARY = @TEST_SLEEP_FOREVER_BINARY@
+TEST_SOCKET_DIR = @TEST_SOCKET_DIR@
+TEST_VALID_SERVICE_DIR = @TEST_VALID_SERVICE_DIR@
+TEST_VALID_SERVICE_SYSTEM_DIR = @TEST_VALID_SERVICE_SYSTEM_DIR@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+XMLTO = @XMLTO@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+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=\""$(localstatedir)/lib/dbus/machine-id"\"
+dbus_send_SOURCES = \
+ dbus-print-message.c \
+ dbus-print-message.h \
+ dbus-send.c
+
+dbus_monitor_SOURCES = \
+ dbus-monitor.c \
+ dbus-print-message.c \
+ dbus-print-message.h
+
+dbus_launch_SOURCES = \
+ dbus-launch.c \
+ dbus-launch-x11.c \
+ dbus-launch.h
+
+dbus_cleanup_sockets_SOURCES = \
+ dbus-cleanup-sockets.c
+
+dbus_uuidgen_SOURCES = \
+ dbus-uuidgen.c
+
+dbus_send_LDADD = $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_send_LDFLAGS = @R_DYNAMIC_LDFLAG@
+dbus_monitor_LDADD = $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_monitor_LDFLAGS = @R_DYNAMIC_LDFLAG@
+dbus_uuidgen_LDADD = $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS)
+dbus_uuidgen_LDFLAGS = @R_DYNAMIC_LDFLAG@
+dbus_launch_LDADD = $(DBUS_X_LIBS) $(DBUS_CLIENT_LIBS)
+dbus_launch_LDFLAGS = @R_DYNAMIC_LDFLAG@
+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
+
+
+#create the /var/lib/data directory for dbus-uuidgen
+localstatelibdir = $(localstatedir)/lib/dbus
+localstatelib_DATA =
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+dbus-cleanup-sockets$(EXEEXT): $(dbus_cleanup_sockets_OBJECTS) $(dbus_cleanup_sockets_DEPENDENCIES)
+ @rm -f dbus-cleanup-sockets$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(dbus_cleanup_sockets_OBJECTS) $(dbus_cleanup_sockets_LDADD) $(LIBS)
+dbus-launch$(EXEEXT): $(dbus_launch_OBJECTS) $(dbus_launch_DEPENDENCIES)
+ @rm -f dbus-launch$(EXEEXT)
+ $(AM_V_CCLD)$(dbus_launch_LINK) $(dbus_launch_OBJECTS) $(dbus_launch_LDADD) $(LIBS)
+dbus-monitor$(EXEEXT): $(dbus_monitor_OBJECTS) $(dbus_monitor_DEPENDENCIES)
+ @rm -f dbus-monitor$(EXEEXT)
+ $(AM_V_CCLD)$(dbus_monitor_LINK) $(dbus_monitor_OBJECTS) $(dbus_monitor_LDADD) $(LIBS)
+dbus-send$(EXEEXT): $(dbus_send_OBJECTS) $(dbus_send_DEPENDENCIES)
+ @rm -f dbus-send$(EXEEXT)
+ $(AM_V_CCLD)$(dbus_send_LINK) $(dbus_send_OBJECTS) $(dbus_send_LDADD) $(LIBS)
+dbus-uuidgen$(EXEEXT): $(dbus_uuidgen_OBJECTS) $(dbus_uuidgen_DEPENDENCIES)
+ @rm -f dbus-uuidgen$(EXEEXT)
+ $(AM_V_CCLD)$(dbus_uuidgen_LINK) $(dbus_uuidgen_OBJECTS) $(dbus_uuidgen_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-cleanup-sockets.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-launch-x11.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-launch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-monitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-print-message.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-send.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-uuidgen.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
+install-localstatelibDATA: $(localstatelib_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(localstatelibdir)" || $(MKDIR_P) "$(DESTDIR)$(localstatelibdir)"
+ @list='$(localstatelib_DATA)'; test -n "$(localstatelibdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(localstatelibdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(localstatelibdir)" || exit $$?; \
+ done
+
+uninstall-localstatelibDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(localstatelib_DATA)'; test -n "$(localstatelibdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(localstatelibdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(localstatelibdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(localstatelibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-localstatelibDATA install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-localstatelibDATA \
+ uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-localstatelibDATA install-man install-man1 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-localstatelibDATA uninstall-man uninstall-man1
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/dbus-cleanup-sockets.1 b/tools/dbus-cleanup-sockets.1
new file mode 100644
index 00000000..ca669f49
--- /dev/null
+++ b/tools/dbus-cleanup-sockets.1
@@ -0,0 +1,43 @@
+.\"
+.\" dbus-cleanup-sockets manual page.
+.\" Copyright (C) 2003 Red Hat, Inc.
+.\"
+.TH dbus-cleanup-sockets 1
+.SH NAME
+dbus-cleanup-sockets \- clean up leftover sockets in a directory
+.SH SYNOPSIS
+.PP
+.B dbus-cleanup-sockets [DIRECTORY]
+
+.SH DESCRIPTION
+
+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
+If given no arguments, \fIdbus-cleanup-sockets\fP cleans up sockets
+in the standard default socket directory for the
+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.
+
+.SH BUGS
+Please send bug reports to the D-Bus mailing list or bug tracker,
+see http://www.freedesktop.org/software/dbus/
diff --git a/tools/dbus-cleanup-sockets.c b/tools/dbus-cleanup-sockets.c
new file mode 100644
index 00000000..487c4b07
--- /dev/null
+++ b/tools/dbus-cleanup-sockets.c
@@ -0,0 +1,431 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-cleanup-sockets.c dbus-cleanup-sockets utility
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ * Copyright (C) 2002 Michael Meeks
+ *
+ * Note that this file is NOT licensed under the Academic Free License,
+ * as it is based on linc-cleanup-sockets which is LGPL.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+static void*
+xmalloc (size_t bytes)
+{
+ void *mem;
+
+ if (bytes == 0)
+ return NULL;
+
+ mem = malloc (bytes);
+
+ if (mem == NULL)
+ {
+ fprintf (stderr, "Allocation of %d bytes failed\n",
+ (int) bytes);
+ exit (1);
+ }
+
+ return mem;
+}
+
+static void*
+xrealloc (void *old, size_t bytes)
+{
+ void *mem;
+
+ if (bytes == 0)
+ {
+ free (old);
+ return NULL;
+ }
+
+ mem = realloc (old, bytes);
+
+ if (mem == NULL)
+ {
+ fprintf (stderr, "Reallocation of %d bytes failed\n",
+ (int) bytes);
+ exit (1);
+ }
+
+ return mem;
+}
+
+#ifdef AF_UNIX
+
+typedef enum
+ {
+ SOCKET_UNKNOWN,
+ SOCKET_FAILED_TO_HANDLE,
+ SOCKET_DEAD,
+ SOCKET_ALIVE,
+ SOCKET_UNLINKED
+ } SocketStatus;
+
+static int alive_count = 0;
+static int cleaned_count = 0;
+static int unhandled_count = 0;
+
+typedef struct
+{
+ char *name;
+ int fd;
+ SocketStatus status;
+ int n_retries;
+} SocketEntry;
+
+static SocketEntry*
+socket_entry_new (const char *dir,
+ const char *fname)
+{
+ SocketEntry *se;
+ int len;
+
+ se = xmalloc (sizeof (SocketEntry));
+
+ len = strlen (dir) + strlen (fname) + 2; /* 2 = nul and '/' */
+ se->name = xmalloc (len);
+
+ strcpy (se->name, dir);
+ strcat (se->name, "/");
+ strcat (se->name, fname);
+
+ se->fd = -1;
+
+ se->status = SOCKET_UNKNOWN;
+
+ se->n_retries = 0;
+
+ return se;
+}
+
+#if 0
+static void
+free_socket_entry (SocketEntry *se)
+{
+ free (se->name);
+ if (se->fd >= 0)
+ close (se->fd);
+ free (se);
+}
+#endif
+
+static void
+read_sockets (const char *dir,
+ SocketEntry ***entries_p,
+ int *n_entries_p)
+{
+ DIR *dirh;
+ struct dirent *dent;
+ SocketEntry **entries;
+ int n_entries;
+ int allocated;
+
+ n_entries = 0;
+ allocated = 2;
+ entries = xmalloc (sizeof (SocketEntry*) * allocated);
+
+ dirh = opendir (dir);
+ if (dirh == NULL)
+ {
+ fprintf (stderr, "Failed to open directory %s: %s\n",
+ dir, strerror (errno));
+ exit (1);
+ }
+
+ while ((dent = readdir (dirh)))
+ {
+ SocketEntry *se;
+
+ if (strncmp (dent->d_name, "dbus-", 5) != 0)
+ continue;
+
+ se = socket_entry_new (dir, dent->d_name);
+
+ if (n_entries == allocated)
+ {
+ allocated *= 2;
+ entries = xrealloc (entries, sizeof (SocketEntry*) * allocated);
+ }
+
+ entries[n_entries] = se;
+ n_entries += 1;
+ }
+
+ closedir (dirh);
+
+ *entries_p = entries;
+ *n_entries_p = n_entries;
+}
+
+static SocketStatus
+open_socket (SocketEntry *se)
+{
+ int ret;
+ struct sockaddr_un saddr;
+
+ if (se->n_retries > 5)
+ {
+ fprintf (stderr, "Warning: giving up on socket %s after several retries; unable to determine socket's status\n",
+ se->name);
+ return SOCKET_FAILED_TO_HANDLE;
+ }
+
+ se->n_retries += 1;
+
+ se->fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (se->fd < 0)
+ {
+ fprintf (stderr, "Warning: failed to open a socket to use for connecting: %s\n",
+ strerror (errno));
+ return SOCKET_UNKNOWN;
+ }
+
+ if (fcntl (se->fd, F_SETFL, O_NONBLOCK) < 0)
+ {
+ fprintf (stderr, "Warning: failed set socket %s nonblocking: %s\n",
+ se->name, strerror (errno));
+ return SOCKET_UNKNOWN;
+ }
+
+
+ memset (&saddr, '\0', sizeof (saddr)); /* nul-terminates the sun_path */
+
+ saddr.sun_family = AF_UNIX;
+ strncpy (saddr.sun_path, se->name, sizeof (saddr.sun_path) - 1);
+
+ do
+ {
+ ret = connect (se->fd, (struct sockaddr*) &saddr, sizeof (saddr));
+ }
+ while (ret < 0 && errno == EINTR);
+
+ if (ret >= 0)
+ return SOCKET_ALIVE;
+ else
+ {
+ switch (errno)
+ {
+ case EINPROGRESS:
+ case EAGAIN:
+ return SOCKET_UNKNOWN;
+ case ECONNREFUSED:
+ return SOCKET_DEAD;
+ default:
+ fprintf (stderr, "Warning: unexpected error connecting to socket %s: %s\n",
+ se->name, strerror (errno));
+ return SOCKET_FAILED_TO_HANDLE;
+ }
+ }
+}
+
+static int
+handle_sockets (SocketEntry **entries,
+ int n_entries)
+{
+ int i;
+ int n_unknown;
+
+ n_unknown = 0;
+
+ i = 0;
+ while (i < n_entries)
+ {
+ SocketEntry *se;
+ SocketStatus status;
+
+ se = entries[i];
+ ++i;
+
+ if (se->fd >= 0)
+ {
+ fprintf (stderr, "Internal error, socket has fd kept open while status = %d\n",
+ se->status);
+ exit (1);
+ }
+
+ if (se->status != SOCKET_UNKNOWN)
+ continue;
+
+ status = open_socket (se);
+
+ switch (status)
+ {
+ case SOCKET_DEAD:
+ cleaned_count += 1;
+ if (unlink (se->name) < 0)
+ {
+ fprintf (stderr, "Warning: Failed to delete %s: %s\n",
+ se->name, strerror (errno));
+
+ se->status = SOCKET_FAILED_TO_HANDLE;
+ }
+ else
+ se->status = SOCKET_UNLINKED;
+ break;
+
+ case SOCKET_ALIVE:
+ alive_count += 1;
+ /* FALL THRU */
+
+ case SOCKET_FAILED_TO_HANDLE:
+ case SOCKET_UNKNOWN:
+ se->status = status;
+ break;
+
+ case SOCKET_UNLINKED:
+ fprintf (stderr, "Bad status from open_socket(), should not happen\n");
+ exit (1);
+ break;
+ }
+
+ if (se->fd >= 0)
+ {
+ close (se->fd);
+ se->fd = -1;
+ }
+
+ if (se->status == SOCKET_UNKNOWN)
+ n_unknown += 1;
+ }
+
+ return n_unknown == 0;
+}
+
+static void
+clean_dir (const char *dir)
+{
+ SocketEntry **entries;
+ int n_entries;
+
+ read_sockets (dir, &entries, &n_entries);
+
+ /* open_socket() will fail conclusively after
+ * several retries, so this loop is guaranteed
+ * to terminate eventually
+ */
+ while (!handle_sockets (entries, n_entries))
+ {
+ fprintf (stderr, "Unable to determine state of some sockets, retrying in 2 seconds\n");
+ sleep (2);
+ }
+
+ unhandled_count += (n_entries - alive_count - cleaned_count);
+}
+
+#endif /* AF_UNIX */
+
+static void
+usage (int ecode)
+{
+ fprintf (stderr, "dbus-cleanup-sockets [--version] [--help] <socketdir>\n");
+ exit (ecode);
+}
+
+static void
+version (void)
+{
+ printf ("D-Bus Socket Cleanup Utility %s\n"
+ "Copyright (C) 2003 Red Hat, Inc.\n"
+ "Copyright (C) 2002 Michael Meeks\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);
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int saw_doubledash;
+ const char *dirname;
+
+ saw_doubledash = FALSE;
+ dirname = NULL;
+ i = 1;
+ while (i < argc)
+ {
+ const char *arg = argv[i];
+
+ if (strcmp (arg, "--help") == 0 ||
+ strcmp (arg, "-h") == 0 ||
+ strcmp (arg, "-?") == 0)
+ usage (0);
+ else if (strcmp (arg, "--version") == 0)
+ version ();
+ else if (!saw_doubledash)
+ {
+ if (strcmp (arg, "--") == 0)
+ saw_doubledash = TRUE;
+ else if (*arg == '-')
+ usage (1);
+ }
+ else
+ {
+ if (dirname != NULL)
+ {
+ fprintf (stderr, "dbus-cleanup-sockets only supports a single directory name\n");
+ exit (1);
+ }
+
+ dirname = arg;
+ }
+
+ ++i;
+ }
+
+ /* Default to session socket dir, usually /tmp */
+ if (dirname == NULL)
+ dirname = DBUS_SESSION_SOCKET_DIR;
+
+#ifdef AF_UNIX
+ clean_dir (dirname);
+
+ printf ("Cleaned up %d sockets in %s; %d sockets are still in use; %d in unknown state\n",
+ cleaned_count, dirname, alive_count, unhandled_count);
+#else
+ printf ("This system does not support UNIX domain sockets, so dbus-cleanup-sockets does nothing\n");
+#endif
+
+ return 0;
+}
diff --git a/tools/dbus-launch-x11.c b/tools/dbus-launch-x11.c
new file mode 100644
index 00000000..56d7f744
--- /dev/null
+++ b/tools/dbus-launch-x11.c
@@ -0,0 +1,463 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-launch.h dbus-launch utility
+ *
+ * Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include "dbus-launch.h"
+
+#ifdef DBUS_BUILD_X11
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+Display *xdisplay = NULL;
+static Atom selection_atom;
+static Atom address_atom;
+static Atom pid_atom;
+
+static int
+x_io_error_handler (Display *xdisplay)
+{
+ verbose ("X IO error\n");
+ kill_bus_and_exit (0);
+ return 0;
+}
+
+static void
+remove_prefix (char *s,
+ char *prefix)
+{
+ int plen;
+
+ plen = strlen (prefix);
+
+ if (strncmp (s, prefix, plen) == 0)
+ {
+ memmove (s, s + plen, strlen (s) - plen + 1);
+ }
+}
+
+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;
+ }
+
+ if (home == NULL)
+ {
+ fprintf (stderr, "Can't get user home directory\n");
+ exit (1);
+ }
+
+ return home;
+}
+
+#define DBUS_DIR ".dbus"
+#define DBUS_SESSION_BUS_DIR "session-bus"
+
+static char *
+get_session_file (void)
+{
+ static const char prefix[] = "/" DBUS_DIR "/" DBUS_SESSION_BUS_DIR "/";
+ const char *machine;
+ const char *home;
+ char *display;
+ char *result;
+ char *p;
+
+ machine = get_machine_uuid ();
+ if (machine == NULL)
+ return NULL;
+
+ display = xstrdup (getenv ("DISPLAY"));
+ if (display == NULL)
+ {
+ verbose ("X11 integration disabled because X11 is not running\n");
+ return NULL;
+ }
+
+ /* remove the screen part of the display name */
+ p = strrchr (display, ':');
+ if (p != NULL)
+ {
+ for ( ; *p; ++p)
+ {
+ if (*p == '.')
+ {
+ *p = '\0';
+ break;
+ }
+ }
+ }
+
+ /* 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 = '_';
+ }
+
+ home = get_homedir ();
+
+ result = malloc (strlen (home) + strlen (prefix) + strlen (machine) +
+ strlen (display) + 2);
+ if (result == NULL)
+ {
+ /* out of memory */
+ free (display);
+ return NULL;
+ }
+
+ strcpy (result, home);
+ strcat (result, prefix);
+ strcat (result, machine);
+ strcat (result, "-");
+ strcat (result, display);
+ free (display);
+
+ verbose ("session file: %s\n", result);
+ 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)
+{
+ if (xdisplay != NULL)
+ return xdisplay;
+
+ xdisplay = XOpenDisplay (NULL);
+ if (xdisplay != NULL)
+ {
+ verbose ("Connected to X11 display '%s'\n", DisplayString (xdisplay));
+ XSetIOErrorHandler (x_io_error_handler);
+ }
+ return xdisplay;
+}
+
+static int
+init_x_atoms (Display *display)
+{
+ 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;
+ const char *machine;
+ char *user_name;
+ struct passwd *user;
+
+ if (init)
+ return TRUE;
+
+ machine = get_machine_uuid ();
+ if (machine == NULL)
+ return FALSE;
+
+ user = getpwuid (getuid ());
+ if (user == NULL)
+ {
+ verbose ("Could not determine the user informations; aborting X11 integration.\n");
+ return FALSE;
+ }
+ user_name = xstrdup(user->pw_name);
+
+ atom_name = malloc (strlen (machine) + strlen (user_name) + 2 +
+ MAX (strlen (selection_prefix),
+ MAX (strlen (address_prefix),
+ strlen (pid_prefix))));
+ if (atom_name == NULL)
+ {
+ verbose ("Could not create X11 atoms; aborting X11 integration.\n");
+ free (user_name);
+ return FALSE;
+ }
+
+ /* create the selection atom */
+ strcpy (atom_name, selection_prefix);
+ strcat (atom_name, user_name);
+ strcat (atom_name, "_");
+ strcat (atom_name, machine);
+ selection_atom = XInternAtom (display, atom_name, FALSE);
+
+ /* create the address property atom */
+ strcpy (atom_name, address_prefix);
+ address_atom = XInternAtom (display, atom_name, FALSE);
+
+ /* create the PID property atom */
+ strcpy (atom_name, pid_prefix);
+ pid_atom = XInternAtom (display, atom_name, FALSE);
+
+ free (atom_name);
+ free (user_name);
+ init = TRUE;
+ return TRUE;
+}
+
+/*
+ * Gets the daemon address from the X11 display.
+ * Returns FALSE if there was an error. Returning
+ * TRUE does not mean the address exists.
+ */
+int
+x11_get_address (char **paddress, pid_t *pid, long *wid)
+{
+ Atom type;
+ Window owner;
+ int format;
+ unsigned long items;
+ unsigned long after;
+ char *data;
+
+ *paddress = NULL;
+
+ /* locate the selection owner */
+ owner = XGetSelectionOwner (xdisplay, selection_atom);
+ if (owner == None)
+ return TRUE; /* no owner */
+ if (wid != NULL)
+ *wid = (long) owner;
+
+ /* get the bus address */
+ XGetWindowProperty (xdisplay, owner, address_atom, 0, 1024, False,
+ XA_STRING, &type, &format, &items, &after,
+ (unsigned char **) &data);
+ if (type == None || after != 0 || data == NULL || format != 8)
+ return FALSE; /* error */
+
+ *paddress = xstrdup (data);
+ XFree (data);
+
+ /* get the PID */
+ if (pid != NULL)
+ {
+ *pid = 0;
+ XGetWindowProperty (xdisplay, owner, pid_atom, 0, sizeof pid, False,
+ XA_CARDINAL, &type, &format, &items, &after,
+ (unsigned char **) &data);
+ if (type != None && after == 0 && data != NULL && format == 32)
+ *pid = (pid_t) *(long*) data;
+ XFree (data);
+ }
+
+ return TRUE; /* success */
+}
+
+/*
+ * Saves the address in the X11 display. Returns 0 on success.
+ * If an error occurs, returns -1. If the selection already exists,
+ * returns 1. (i.e. another daemon is already running)
+ */
+static Window
+set_address_in_x11(char *address, pid_t pid)
+{
+ char *current_address;
+ Window wid = None;
+ unsigned long pid32; /* Xlib property functions want _long_ not 32-bit for format "32" */
+
+ /* lock the X11 display to make sure we're doing this atomically */
+ XGrabServer (xdisplay);
+
+ if (!x11_get_address (&current_address, NULL, NULL))
+ {
+ /* error! */
+ goto out;
+ }
+
+ if (current_address != NULL)
+ {
+ /* someone saved the address in the meantime */
+ free (current_address);
+ goto out;
+ }
+
+ /* Create our window */
+ wid = XCreateWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10,
+ 0, CopyFromParent, InputOnly, CopyFromParent,
+ 0, NULL);
+ verbose ("Created window %d\n", wid);
+
+ /* Save the property in the window */
+ XChangeProperty (xdisplay, wid, address_atom, XA_STRING, 8, PropModeReplace,
+ (unsigned char *)address, strlen (address));
+ pid32 = pid;
+ XChangeProperty (xdisplay, wid, pid_atom, XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *)&pid32, 1);
+
+ /* Now grab the selection */
+ XSetSelectionOwner (xdisplay, selection_atom, wid, CurrentTime);
+
+ out:
+ /* Ungrab the server to let other people use it too */
+ XUngrabServer (xdisplay);
+
+ /* And make sure that the ungrab gets sent to X11 */
+ XFlush (xdisplay);
+
+ return wid;
+}
+
+/*
+ * Saves the session address in session file. Returns TRUE on
+ * success, FALSE if an error occurs.
+ */
+static int
+set_address_in_file (char *address, pid_t pid, Window wid)
+{
+ char *session_file;
+ FILE *f;
+
+ ensure_session_directory ();
+ session_file = get_session_file();
+ if (session_file == NULL)
+ return FALSE;
+
+ f = fopen (session_file, "w");
+ if (f == NULL)
+ return FALSE; /* some kind of error */
+ 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);
+
+ return TRUE;
+}
+
+int
+x11_save_address (char *address, pid_t pid, long *wid)
+{
+ Window id = set_address_in_x11 (address, pid);
+ if (id != None)
+ {
+ if (!set_address_in_file (address, pid, id))
+ return FALSE;
+
+ if (wid != NULL)
+ *wid = (long) id;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+x11_init (void)
+{
+ return open_x11 () != NULL && init_x_atoms (xdisplay);
+}
+
+void
+x11_handle_event (void)
+{
+ if (xdisplay != NULL)
+ {
+ while (XPending (xdisplay))
+ {
+ XEvent ignored;
+ XNextEvent (xdisplay, &ignored);
+ }
+ }
+}
+
+#else
+void dummy_dbus_launch_x11 (void) { }
+#endif
diff --git a/tools/dbus-launch.1 b/tools/dbus-launch.1
new file mode 100644
index 00000000..0ea19495
--- /dev/null
+++ b/tools/dbus-launch.1
@@ -0,0 +1,183 @@
+.\"
+.\" dbus-launch manual page.
+.\" Copyright (C) 2003 Red Hat, Inc.
+.\"
+.TH dbus-launch 1
+.SH NAME
+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=MACHINEID] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
+
+.SH DESCRIPTION
+
+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 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 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.
+
+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
+should be used. If SHELL ends in "csh", then csh-compatible code is
+emitted; otherwise Bourne shell code is emitted. Instead of passing
+\-\-auto-syntax, you may explicity specify a particular one by using
+\-\-sh-syntax for Bourne syntax, or \-\-csh-syntax for csh syntax.
+In scripts, it's more robust to avoid \-\-auto-syntax and you hopefully
+know which shell your script is written in.
+
+.PP
+See http://www.freedesktop.org/software/dbus/ for more information
+about D-Bus. See also the man page for \fIdbus-daemon\fP.
+
+.PP
+Here is an example of how to use \fIdbus-launch\fP with an
+sh-compatible shell to start the per-session bus daemon:
+.nf
+
+ ## test for an existing bus daemon, just to be safe
+ if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
+ ## if not found, launch a new one
+ eval `dbus-launch --sh-syntax --exit-with-session`
+ echo "D-Bus per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
+ fi
+
+.fi
+You might run something like that in your login scripts.
+
+.PP
+Another way to use \fIdbus-launch\fP is to run your main session
+program, like so:
+.nf
+
+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.)
+
+.PP
+The --autolaunch option is considered an internal implementation
+detail of libdbus, and in fact there are plans to change it. There's
+no real reason to use it outside of the libdbus implementation anyhow.
+
+.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 "--close-stderr"
+Close the standard error output stream before starting the D-Bus
+daemon. This is useful if you want to capture dbus-launch error
+messages but you don't want dbus-daemon to keep the stream open to
+your application.
+
+.TP
+.I "--config-file=FILENAME"
+Pass \-\-config-file=FILENAME to the bus daemon, instead of passing it
+the \-\-session argument. See the man page for dbus-daemon
+
+.TP
+.I "--csh-syntax"
+Emit csh compatible code to set up environment variables.
+
+.TP
+.I "--exit-with-session"
+If this option is provided, a persistent "babysitter" process will be
+created that watches stdin for HUP and tries to connect to the X
+server. If this process gets a HUP on stdin or loses its X connection,
+it kills the message bus daemon.
+
+.TP
+.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 for the exclusive use of libdbus, you do not want to
+use it manually. It may change in the future.
+
+.TP
+.I "--sh-syntax"
+Emit Bourne-shell compatible code to set up environment variables.
+
+.TP
+.I "--version"
+Print the version of dbus-launch
+
+.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/
diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c
new file mode 100644
index 00000000..d3553e81
--- /dev/null
+++ b/tools/dbus-launch.c
@@ -0,0 +1,1214 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-launch.c dbus-launch utility
+ *
+ * Copyright (C) 2003, 2006 Red Hat, Inc.
+ * Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include "dbus-launch.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <sys/select.h>
+#include <time.h>
+
+#ifdef DBUS_BUILD_X11
+#include <X11/Xlib.h>
+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);
+}
+
+#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,
+ ...)
+{
+ va_list args;
+ static int verbose = TRUE;
+ static int verbose_initted = FALSE;
+
+ /* things are written a bit oddly here so that
+ * in the non-verbose case we just have the one
+ * conditional and return immediately.
+ */
+ if (!verbose)
+ return;
+
+ if (!verbose_initted)
+ {
+ verbose = getenv ("DBUS_VERBOSE") != NULL;
+ verbose_initted = TRUE;
+ if (!verbose)
+ return;
+ }
+
+ fprintf (stderr, "%lu: ", (unsigned long) getpid ());
+
+ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+}
+
+static void
+usage (int ecode)
+{
+ fprintf (stderr, "dbus-launch [--version] [--help] [--sh-syntax] [--csh-syntax] [--auto-syntax] [--exit-with-session]\n");
+ exit (ecode);
+}
+
+static void
+version (void)
+{
+ printf ("D-Bus Message Bus Launcher %s\n"
+ "Copyright (C) 2003 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);
+}
+
+char *
+xstrdup (const char *str)
+{
+ int len;
+ char *copy;
+
+ if (str == NULL)
+ return NULL;
+
+ len = strlen (str);
+
+ copy = malloc (len + 1);
+ if (copy == NULL)
+ return NULL;
+
+ memcpy (copy, str, len + 1);
+
+ return copy;
+}
+
+typedef enum
+{
+ READ_STATUS_OK, /**< Read succeeded */
+ READ_STATUS_ERROR, /**< Some kind of error */
+ READ_STATUS_EOF /**< EOF returned */
+} ReadStatus;
+
+static ReadStatus
+read_line (int fd,
+ char *buf,
+ size_t maxlen)
+{
+ size_t bytes = 0;
+ ReadStatus retval;
+
+ memset (buf, '\0', maxlen);
+ maxlen -= 1; /* ensure nul term */
+
+ retval = READ_STATUS_OK;
+
+ while (TRUE)
+ {
+ ssize_t chunk;
+ size_t to_read;
+
+ again:
+ to_read = maxlen - bytes;
+
+ if (to_read == 0)
+ break;
+
+ chunk = read (fd,
+ buf + bytes,
+ to_read);
+ if (chunk < 0 && errno == EINTR)
+ goto again;
+
+ if (chunk < 0)
+ {
+ retval = READ_STATUS_ERROR;
+ break;
+ }
+ else if (chunk == 0)
+ {
+ retval = READ_STATUS_EOF;
+ break; /* EOF */
+ }
+ else /* chunk > 0 */
+ bytes += chunk;
+ }
+
+ if (retval == READ_STATUS_EOF &&
+ bytes > 0)
+ retval = READ_STATUS_OK;
+
+ /* whack newline */
+ if (retval != READ_STATUS_ERROR &&
+ bytes > 0 &&
+ buf[bytes-1] == '\n')
+ buf[bytes-1] = '\0';
+
+ return retval;
+}
+
+static ReadStatus
+read_pid (int fd,
+ pid_t *buf)
+{
+ size_t bytes = 0;
+ ReadStatus retval;
+
+ retval = READ_STATUS_OK;
+
+ while (TRUE)
+ {
+ ssize_t chunk;
+ size_t to_read;
+
+ again:
+ to_read = sizeof (pid_t) - bytes;
+
+ if (to_read == 0)
+ break;
+
+ chunk = read (fd,
+ ((char*)buf) + bytes,
+ to_read);
+ if (chunk < 0 && errno == EINTR)
+ goto again;
+
+ if (chunk < 0)
+ {
+ retval = READ_STATUS_ERROR;
+ break;
+ }
+ else if (chunk == 0)
+ {
+ retval = READ_STATUS_EOF;
+ break; /* EOF */
+ }
+ else /* chunk > 0 */
+ bytes += chunk;
+ }
+
+ return retval;
+}
+
+static void
+do_write (int fd, const void *buf, size_t count)
+{
+ size_t bytes_written;
+ int ret;
+
+ bytes_written = 0;
+
+ again:
+
+ ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
+
+ if (ret < 0)
+ {
+ if (errno == EINTR)
+ goto again;
+ else
+ {
+ fprintf (stderr, "Failed to write data to pipe! %s\n",
+ strerror (errno));
+ exit (1); /* give up, we suck */
+ }
+ }
+ else
+ bytes_written += ret;
+
+ if (bytes_written < count)
+ goto again;
+}
+
+static void
+write_pid (int fd,
+ pid_t pid)
+{
+ do_write (fd, &pid, sizeof (pid));
+}
+
+static int
+do_waitpid (pid_t pid)
+{
+ int ret;
+
+ again:
+ ret = waitpid (pid, NULL, 0);
+
+ if (ret < 0 &&
+ errno == EINTR)
+ goto again;
+
+ return ret;
+}
+
+static pid_t bus_pid_to_kill = -1;
+
+static void
+kill_bus(void)
+{
+ 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)
+{
+ /* in case these point to any NFS mounts, get rid of them immediately */
+ close (0);
+ close (1);
+ close (2);
+
+ kill_bus();
+
+ exit (exitcode);
+}
+
+static void
+print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
+ int c_shell_syntax, int bourne_shell_syntax,
+ int binary_syntax)
+{
+ if (binary_syntax)
+ {
+ write (1, bus_address, strlen (bus_address) + 1);
+ write (1, &bus_pid, sizeof bus_pid);
+ write (1, &bus_wid, sizeof bus_wid);
+ return;
+ }
+ else if (c_shell_syntax)
+ {
+ printf ("setenv DBUS_SESSION_BUS_ADDRESS '%s';\n", 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 if (bourne_shell_syntax)
+ {
+ printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
+ printf ("export DBUS_SESSION_BUS_ADDRESS;\n");
+ 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);
+ }
+}
+
+static int got_sighup = FALSE;
+
+static void
+signal_handler (int sig)
+{
+ switch (sig)
+ {
+#ifdef SIGHUP
+ case SIGHUP:
+#endif
+ case SIGINT:
+ case SIGTERM:
+ got_sighup = TRUE;
+ break;
+ }
+}
+
+static void
+kill_bus_when_session_ends (void)
+{
+ int tty_fd;
+ int x_fd;
+ fd_set read_set;
+ fd_set err_set;
+ struct sigaction act;
+ sigset_t empty_mask;
+
+ /* install SIGHUP handler */
+ got_sighup = FALSE;
+ sigemptyset (&empty_mask);
+ act.sa_handler = signal_handler;
+ act.sa_mask = empty_mask;
+ act.sa_flags = 0;
+ sigaction (SIGHUP, &act, NULL);
+ sigaction (SIGTERM, &act, NULL);
+ sigaction (SIGINT, &act, NULL);
+
+#ifdef DBUS_BUILD_X11
+ x11_init();
+ if (xdisplay != NULL)
+ {
+ x_fd = ConnectionNumber (xdisplay);
+ }
+ else
+ x_fd = -1;
+#else
+ x_fd = -1;
+#endif
+
+ if (isatty (0))
+ tty_fd = 0;
+ else
+ tty_fd = -1;
+
+ if (tty_fd >= 0)
+ verbose ("stdin isatty(), monitoring it\n");
+ else
+ verbose ("stdin was not a TTY, not monitoring it\n");
+
+ if (tty_fd < 0 && x_fd < 0)
+ {
+ fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n");
+ exit (1);
+ }
+
+ while (TRUE)
+ {
+#ifdef DBUS_BUILD_X11
+ /* Dump events on the floor, and let
+ * IO error handler run if we lose
+ * the X connection. It's important to
+ * run this before going into select() since
+ * we might have queued outgoing messages or
+ * events.
+ */
+ x11_handle_event ();
+#endif
+
+ FD_ZERO (&read_set);
+ FD_ZERO (&err_set);
+
+ if (tty_fd >= 0)
+ {
+ FD_SET (tty_fd, &read_set);
+ FD_SET (tty_fd, &err_set);
+ }
+
+ if (x_fd >= 0)
+ {
+ FD_SET (x_fd, &read_set);
+ FD_SET (x_fd, &err_set);
+ }
+
+ select (MAX (tty_fd, x_fd) + 1,
+ &read_set, NULL, &err_set, NULL);
+
+ if (got_sighup)
+ {
+ verbose ("Got SIGHUP, exiting\n");
+ kill_bus_and_exit (0);
+ }
+
+#ifdef DBUS_BUILD_X11
+ /* Events will be processed before we select again
+ */
+ if (x_fd >= 0)
+ verbose ("X fd condition reading = %d error = %d\n",
+ FD_ISSET (x_fd, &read_set),
+ FD_ISSET (x_fd, &err_set));
+#endif
+
+ if (tty_fd >= 0)
+ {
+ if (FD_ISSET (tty_fd, &read_set))
+ {
+ int bytes_read;
+ char discard[512];
+
+ verbose ("TTY ready for reading\n");
+
+ bytes_read = read (tty_fd, discard, sizeof (discard));
+
+ verbose ("Read %d bytes from TTY errno = %d\n",
+ bytes_read, errno);
+
+ if (bytes_read == 0)
+ kill_bus_and_exit (0); /* EOF */
+ else if (bytes_read < 0 && errno != EINTR)
+ {
+ /* This shouldn't happen I don't think; to avoid
+ * spinning on the fd forever we exit.
+ */
+ fprintf (stderr, "dbus-launch: error reading from stdin: %s\n",
+ strerror (errno));
+ kill_bus_and_exit (0);
+ }
+ }
+ else if (FD_ISSET (tty_fd, &err_set))
+ {
+ verbose ("TTY has error condition\n");
+
+ kill_bus_and_exit (0);
+ }
+ }
+ }
+}
+
+static void
+babysit (int exit_with_session,
+ pid_t child_pid,
+ int read_bus_pid_fd) /* read pid from here */
+{
+ int ret;
+ int dev_null_fd;
+ const char *s;
+
+ verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d\n",
+ exit_with_session, (long) child_pid, read_bus_pid_fd);
+
+ /* We chdir ("/") since we are persistent and daemon-like, and fork
+ * again so dbus-launch can reap the parent. However, we don't
+ * setsid() or close fd 0 because the idea is to remain attached
+ * to the tty and the X server in order to kill the message bus
+ * when the session ends.
+ */
+
+ if (chdir ("/") < 0)
+ {
+ fprintf (stderr, "Could not change to root directory: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ /* Close stdout/stderr so we don't block an "eval" or otherwise
+ * lock up. stdout is still chaining through to dbus-launch
+ * and in turn to the parent shell.
+ */
+ dev_null_fd = open ("/dev/null", O_RDWR);
+ if (dev_null_fd >= 0)
+ {
+ if (!exit_with_session)
+ dup2 (dev_null_fd, 0);
+ dup2 (dev_null_fd, 1);
+ s = getenv ("DBUS_DEBUG_OUTPUT");
+ if (s == NULL || *s == '\0')
+ dup2 (dev_null_fd, 2);
+ }
+ else
+ {
+ fprintf (stderr, "Failed to open /dev/null: %s\n",
+ strerror (errno));
+ /* continue, why not */
+ }
+
+ ret = fork ();
+
+ if (ret < 0)
+ {
+ fprintf (stderr, "fork() failed in babysitter: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ if (ret > 0)
+ {
+ /* Parent reaps pre-fork part of bus daemon, then exits and is
+ * reaped so the babysitter isn't a zombie
+ */
+
+ verbose ("=== Babysitter's intermediate parent continues again\n");
+
+ if (do_waitpid (child_pid) < 0)
+ {
+ /* shouldn't happen */
+ fprintf (stderr, "Failed waitpid() waiting for bus daemon's parent\n");
+ exit (1);
+ }
+
+ verbose ("Babysitter's intermediate parent exiting\n");
+
+ exit (0);
+ }
+
+ /* Child continues */
+ verbose ("=== Babysitter process created\n");
+
+ verbose ("Reading PID from bus\n");
+
+ switch (read_pid (read_bus_pid_fd, &bus_pid_to_kill))
+ {
+ case READ_STATUS_OK:
+ break;
+ case READ_STATUS_EOF:
+ fprintf (stderr, "EOF in dbus-launch reading PID from bus daemon\n");
+ exit (1);
+ break;
+ case READ_STATUS_ERROR:
+ fprintf (stderr, "Error in dbus-launch reading PID from bus daemon: %s\n",
+ strerror (errno));
+ exit (1);
+ break;
+ }
+
+ verbose ("Got PID %ld from daemon\n",
+ (long) bus_pid_to_kill);
+
+ if (exit_with_session)
+ {
+ /* Bus is now started and launcher has needed info;
+ * we connect to X display and tty and wait to
+ * kill bus if requested.
+ */
+
+ kill_bus_when_session_ends ();
+ }
+
+ verbose ("Babysitter exiting\n");
+
+ exit (0);
+}
+
+static void
+do_close_stderr (void)
+{
+ int fd;
+
+ fflush (stderr);
+
+ /* dbus-launch is a Unix-only program, so we can rely on /dev/null being there.
+ * We're including unistd.h and we're dealing with sh/csh launch sequences...
+ */
+ fd = open ("/dev/null", O_RDWR);
+ if (fd == -1)
+ {
+ fprintf (stderr, "Internal error: cannot open /dev/null: %s", strerror (errno));
+ exit (1);
+ }
+
+ close (2);
+ if (dup2 (fd, 2) == -1)
+ {
+ /* error; we can't report an error anymore... */
+ exit (1);
+ }
+ 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
+
+int
+main (int argc, char **argv)
+{
+ const char *prev_arg;
+ const char *shname;
+ const char *runprog = NULL;
+ int remaining_args = 0;
+ int exit_with_session;
+ int binary_syntax = FALSE;
+ int c_shell_syntax = FALSE;
+ int bourne_shell_syntax = FALSE;
+ int auto_shell_syntax = FALSE;
+ int autolaunch = FALSE;
+ int requires_arg = FALSE;
+ int close_stderr = FALSE;
+ int i;
+ int ret;
+ int bus_pid_to_launcher_pipe[2];
+ int bus_pid_to_babysitter_pipe[2];
+ int bus_address_to_launcher_pipe[2];
+ char *config_file;
+
+ exit_with_session = FALSE;
+ config_file = NULL;
+
+ prev_arg = NULL;
+ i = 1;
+ while (i < argc)
+ {
+ const char *arg = argv[i];
+
+ if (strcmp (arg, "--help") == 0 ||
+ strcmp (arg, "-h") == 0 ||
+ strcmp (arg, "-?") == 0)
+ usage (0);
+ else if (strcmp (arg, "--auto-syntax") == 0)
+ auto_shell_syntax = TRUE;
+ else if (strcmp (arg, "-c") == 0 ||
+ strcmp (arg, "--csh-syntax") == 0)
+ c_shell_syntax = TRUE;
+ else if (strcmp (arg, "-s") == 0 ||
+ strcmp (arg, "--sh-syntax") == 0)
+ bourne_shell_syntax = TRUE;
+ else if (strcmp (arg, "--binary-syntax") == 0)
+ binary_syntax = TRUE;
+ else if (strcmp (arg, "--version") == 0)
+ version ();
+ else if (strcmp (arg, "--exit-with-session") == 0)
+ exit_with_session = TRUE;
+ else if (strcmp (arg, "--close-stderr") == 0)
+ close_stderr = 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);
+ requires_arg = FALSE;
+ }
+ else if (strcmp (arg, "--autolaunch") == 0)
+ requires_arg = TRUE;
+ else if (strstr (arg, "--config-file=") == arg)
+ {
+ const char *file;
+
+ if (config_file != NULL)
+ {
+ fprintf (stderr, "--config-file given twice\n");
+ exit (1);
+ }
+
+ file = strchr (arg, '=');
+ ++file;
+
+ config_file = xstrdup (file);
+ }
+ else if (prev_arg &&
+ strcmp (prev_arg, "--config-file") == 0)
+ {
+ if (config_file != NULL)
+ {
+ fprintf (stderr, "--config-file given twice\n");
+ exit (1);
+ }
+
+ config_file = xstrdup (arg);
+ requires_arg = FALSE;
+ }
+ else if (strcmp (arg, "--config-file") == 0)
+ requires_arg = TRUE;
+ else if (arg[0] == '-')
+ {
+ if (strcmp (arg, "--") != 0)
+ {
+ fprintf (stderr, "Option `%s' is unknown.\n", arg);
+ exit (1);
+ }
+ else
+ {
+ runprog = argv[i+1];
+ remaining_args = i+2;
+ break;
+ }
+ }
+ else
+ {
+ runprog = arg;
+ remaining_args = i+1;
+ break;
+ }
+
+ prev_arg = arg;
+
+ ++i;
+ }
+ if (requires_arg)
+ {
+ fprintf (stderr, "Option `%s' requires an argument.\n", prev_arg);
+ exit (1);
+ }
+
+ if (auto_shell_syntax)
+ {
+ if ((shname = getenv ("SHELL")) != NULL)
+ {
+ if (!strncmp (shname + strlen (shname) - 3, "csh", 3))
+ c_shell_syntax = TRUE;
+ else
+ bourne_shell_syntax = TRUE;
+ }
+ else
+ bourne_shell_syntax = TRUE;
+ }
+
+ if (exit_with_session)
+ 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");
+ exit (1);
+#else
+ 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);
+ }
+
+ verbose ("Autolaunch enabled (using X11).\n");
+ if (!exit_with_session)
+ {
+ verbose ("--exit-with-session automatically enabled\n");
+ exit_with_session = TRUE;
+ }
+
+ if (!x11_init ())
+ {
+ fprintf (stderr, "Autolaunch error: X11 initialization failed.\n");
+ exit (1);
+ }
+
+ if (!x11_get_address (&address, &pid, &wid))
+ {
+ fprintf (stderr, "Autolaunch error: X11 communication error.\n");
+ exit (1);
+ }
+
+ if (address != NULL)
+ {
+ verbose ("dbus-daemon is already running. Returning existing parameters.\n");
+ 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)
+ {
+ fprintf (stderr,
+ "Failed to create pipe: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ ret = fork ();
+ if (ret < 0)
+ {
+ fprintf (stderr, "Failed to fork: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ if (ret == 0)
+ {
+ /* Child */
+#define MAX_FD_LEN 64
+ char write_pid_fd_as_string[MAX_FD_LEN];
+ char write_address_fd_as_string[MAX_FD_LEN];
+
+#ifdef DBUS_BUILD_X11
+ xdisplay = NULL;
+#endif
+
+ if (close_stderr)
+ do_close_stderr ();
+
+ verbose ("=== Babysitter's intermediate parent created\n");
+
+ /* Fork once more to create babysitter */
+
+ ret = fork ();
+ if (ret < 0)
+ {
+ fprintf (stderr, "Failed to fork: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ if (ret > 0)
+ {
+ /* In babysitter */
+ verbose ("=== Babysitter's intermediate parent continues\n");
+
+ close (bus_pid_to_launcher_pipe[READ_END]);
+ close (bus_pid_to_launcher_pipe[WRITE_END]);
+ close (bus_address_to_launcher_pipe[READ_END]);
+ close (bus_address_to_launcher_pipe[WRITE_END]);
+ close (bus_pid_to_babysitter_pipe[WRITE_END]);
+
+ /* babysit() will fork *again*
+ * and will also reap the pre-forked bus
+ * daemon
+ */
+ babysit (exit_with_session, ret,
+ bus_pid_to_babysitter_pipe[READ_END]);
+ exit (0);
+ }
+
+ verbose ("=== Bus exec process created\n");
+
+ /* Now we are the bus process (well, almost;
+ * dbus-daemon itself forks again)
+ */
+ close (bus_pid_to_launcher_pipe[READ_END]);
+ close (bus_address_to_launcher_pipe[READ_END]);
+ close (bus_pid_to_babysitter_pipe[READ_END]);
+ close (bus_pid_to_babysitter_pipe[WRITE_END]);
+
+ sprintf (write_pid_fd_as_string,
+ "%d", bus_pid_to_launcher_pipe[WRITE_END]);
+
+ sprintf (write_address_fd_as_string,
+ "%d", bus_address_to_launcher_pipe[WRITE_END]);
+
+ verbose ("Calling exec()\n");
+
+#ifdef DBUS_BUILD_TESTS
+ /* exec from testdir */
+ if (getenv("DBUS_USE_TEST_BINARY") != NULL)
+ {
+ execl (TEST_BUS_BINARY,
+ TEST_BUS_BINARY,
+ "--fork",
+ "--print-pid", write_pid_fd_as_string,
+ "--print-address", write_address_fd_as_string,
+ config_file ? "--config-file" : "--session",
+ config_file, /* has to be last in this varargs list */
+ NULL);
+
+ fprintf (stderr,
+ "Failed to execute test message bus daemon %s: %s. Will try again with the system path.\n",
+ TEST_BUS_BINARY, strerror (errno));
+ }
+ #endif /* DBUS_BUILD_TESTS */
+
+ execl (DBUS_DAEMONDIR"/dbus-daemon",
+ DBUS_DAEMONDIR"/dbus-daemon",
+ "--fork",
+ "--print-pid", write_pid_fd_as_string,
+ "--print-address", write_address_fd_as_string,
+ config_file ? "--config-file" : "--session",
+ config_file, /* has to be last in this varargs list */
+ NULL);
+
+ fprintf (stderr,
+ "Failed to execute message bus daemon %s: %s. Will try again without full path.\n",
+ DBUS_DAEMONDIR"/dbus-daemon", strerror (errno));
+
+ /*
+ * If it failed, try running without full PATH. Note this is needed
+ * because the build process builds the run-with-tmp-session-bus.conf
+ * file and the dbus-daemon will not be in the install location during
+ * build time.
+ */
+ execlp ("dbus-daemon",
+ "dbus-daemon",
+ "--fork",
+ "--print-pid", write_pid_fd_as_string,
+ "--print-address", write_address_fd_as_string,
+ config_file ? "--config-file" : "--session",
+ config_file, /* has to be last in this varargs list */
+ NULL);
+
+ fprintf (stderr,
+ "Failed to execute message bus daemon: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+ else
+ {
+ /* Parent */
+#define MAX_PID_LEN 64
+ pid_t bus_pid;
+ char bus_address[MAX_ADDR_LEN];
+ char buf[MAX_PID_LEN];
+ char *end;
+ long wid = 0;
+ long val;
+ int ret2;
+
+ verbose ("=== Parent dbus-launch continues\n");
+
+ close (bus_pid_to_launcher_pipe[WRITE_END]);
+ close (bus_address_to_launcher_pipe[WRITE_END]);
+ close (bus_pid_to_babysitter_pipe[READ_END]);
+
+ verbose ("Waiting for babysitter's intermediate parent\n");
+
+ /* Immediately reap parent of babysitter
+ * (which was created just for us to reap)
+ */
+ if (do_waitpid (ret) < 0)
+ {
+ fprintf (stderr, "Failed to waitpid() for babysitter intermediate process: %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ verbose ("Reading address from bus\n");
+
+ /* Read the pipe data, print, and exit */
+ switch (read_line (bus_address_to_launcher_pipe[READ_END],
+ bus_address, MAX_ADDR_LEN))
+ {
+ case READ_STATUS_OK:
+ break;
+ case READ_STATUS_EOF:
+ fprintf (stderr, "EOF in dbus-launch reading address from bus daemon\n");
+ exit (1);
+ break;
+ case READ_STATUS_ERROR:
+ fprintf (stderr, "Error in dbus-launch reading address from bus daemon: %s\n",
+ strerror (errno));
+ exit (1);
+ break;
+ }
+
+ close (bus_address_to_launcher_pipe[READ_END]);
+
+ verbose ("Reading PID from daemon\n");
+ /* Now read data */
+ switch (read_line (bus_pid_to_launcher_pipe[READ_END], buf, MAX_PID_LEN))
+ {
+ case READ_STATUS_OK:
+ break;
+ case READ_STATUS_EOF:
+ fprintf (stderr, "EOF reading PID from bus daemon\n");
+ exit (1);
+ break;
+ case READ_STATUS_ERROR:
+ fprintf (stderr, "Error reading PID from bus daemon: %s\n",
+ strerror (errno));
+ exit (1);
+ break;
+ }
+
+ end = NULL;
+ val = strtol (buf, &end, 0);
+ if (buf == end || end == NULL)
+ {
+ fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n",
+ buf, strerror (errno));
+ exit (1);
+ }
+
+ bus_pid = val;
+
+ close (bus_pid_to_launcher_pipe[READ_END]);
+
+#ifdef DBUS_BUILD_X11
+ if (xdisplay != NULL)
+ {
+ verbose("Saving x11 address\n");
+ ret2 = x11_save_address (bus_address, bus_pid, &wid);
+ /* Only get an existing dbus session when autolaunching */
+ if (autolaunch)
+ {
+ if (ret2 == 0)
+ {
+ char *address = NULL;
+ /* another window got added. Return its address */
+ bus_pid_to_kill = bus_pid;
+ 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);
+ }
+ }
+ }
+#endif
+
+ /* Forward the pid to the babysitter */
+ write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid);
+ close (bus_pid_to_babysitter_pipe[WRITE_END]);
+
+ pass_info (runprog, bus_address, bus_pid, wid, c_shell_syntax,
+ bourne_shell_syntax, binary_syntax, argc, argv, remaining_args);
+ }
+
+ return 0;
+}
diff --git a/tools/dbus-launch.h b/tools/dbus-launch.h
new file mode 100644
index 00000000..d0d0617d
--- /dev/null
+++ b/tools/dbus-launch.h
@@ -0,0 +1,58 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-launch.h dbus-launch utility
+ *
+ * Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_LAUNCH_H
+#define DBUS_LAUNCH_H
+
+#include <config.h>
+#include <sys/types.h>
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#undef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define MAX_ADDR_LEN 512
+
+/* defined in dbus-launch.c */
+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);
+int x11_get_address (char **paddress, pid_t *pid, long *wid);
+int x11_save_address (char *address, pid_t pid, long *wid);
+void x11_handle_event (void);
+#endif
+
+#endif
diff --git a/tools/dbus-monitor.1 b/tools/dbus-monitor.1
new file mode 100644
index 00000000..c24c14d9
--- /dev/null
+++ b/tools/dbus-monitor.1
@@ -0,0 +1,78 @@
+.\"
+.\" dbus-monitor manual page.
+.\" Copyright (C) 2003 Red Hat, Inc.
+.\"
+.TH dbus-monitor 1
+.SH NAME
+dbus-monitor \- debug probe to print message bus messages
+.SH SYNOPSIS
+.PP
+.B dbus-monitor
+[\-\-system | \-\-session | \-\-address ADDRESS] [\-\-profile | \-\-monitor]
+[watch expressions]
+
+.SH DESCRIPTION
+
+The \fIdbus-monitor\fP command is used to monitor messages going
+through a D-Bus message bus. See
+http://www.freedesktop.org/software/dbus/ for more information about
+the big picture.
+
+.PP
+There are two well-known message buses: the systemwide message bus
+(installed on many systems as the "messagebus" service) and the
+per-user-login-session message bus (started each time a user logs in).
+The \-\-system and \-\-session options direct \fIdbus-monitor\fP to
+monitor the system or session buses respectively. If neither is
+specified, \fIdbus-monitor\fP monitors the session bus.
+
+.PP
+\fIdbus-monitor\fP has two different output modes, the 'classic'-style
+monitoring mode and profiling mode. The profiling format is a compact
+format with a single line per message and microsecond-resolution timing
+information. The \-\-profile and \-\-monitor options select the profiling
+and monitoring output format respectively. If neither is specified,
+\fIdbus-monitor\fP uses the monitoring output format.
+
+.PP
+In order to get \fIdbus-monitor\fP to see the messages you are interested
+in, you should specify a set of watch expressions as you would expect to
+be passed to the \fIdbus_bus_add_match\fP function.
+
+.PP
+The message bus configuration may keep \fIdbus-monitor\fP from seeing
+all messages, especially if you run the monitor as a non-root user.
+
+.SH OPTIONS
+.TP
+.I "--system"
+Monitor the system message bus.
+.TP
+.I "--session"
+Monitor the session message bus. (This is the default.)
+.TP
+.I "--address ADDRESS"
+Monitor an arbitrary message bus given at ADDRESS.
+.TP
+.I "--profile"
+Use the profiling output format.
+.TP
+.I "--monitor"
+Use the monitoring output format. (This is the default.)
+
+.SH EXAMPLE
+Here is an example of using dbus-monitor to watch for the gnome typing
+monitor to say things
+.nf
+
+ dbus-monitor "type='signal',sender='org.gnome.TypingMonitor',interface='org.gnome.TypingMonitor'"
+
+.fi
+
+.SH AUTHOR
+dbus-monitor was written by Philip Blundell.
+The profiling output mode was added by Olli Salli.
+
+.SH BUGS
+Please send bug reports to the D-Bus mailing list or bug tracker,
+see http://www.freedesktop.org/software/dbus/
diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c
new file mode 100644
index 00000000..c3681289
--- /dev/null
+++ b/tools/dbus-monitor.c
@@ -0,0 +1,354 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-monitor.c Utility program to monitor messages on the bus
+ *
+ * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DBUS_WIN
+#include <winsock2.h>
+#undef interface
+#else
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+
+#include "dbus-print-message.h"
+
+#ifdef DBUS_WIN
+
+/* gettimeofday is not defined on windows */
+#define DBUS_SECONDS_SINCE_1601 11644473600LL
+#define DBUS_USEC_IN_SEC 1000000LL
+
+static int
+gettimeofday (struct timeval *__p,
+ void *__t)
+{
+ union {
+ unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
+ FILETIME ft;
+ } now;
+
+ GetSystemTimeAsFileTime (&now.ft);
+ __p->tv_usec = (long) ((now.ns100 / 10LL) % DBUS_USEC_IN_SEC);
+ __p->tv_sec = (long)(((now.ns100 / 10LL) / DBUS_SECONDS_SINCE_1601) - DBUS_SECONDS_SINCE_1601);
+
+ return 0;
+}
+#endif
+
+static DBusHandlerResult
+monitor_filter_func (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ print_message (message, FALSE);
+
+ if (dbus_message_is_signal (message,
+ DBUS_INTERFACE_LOCAL,
+ "Disconnected"))
+ exit (0);
+
+ /* Conceptually we want this to be
+ * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
+ * some problems. See bug 1719.
+ */
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+#define PROFILE_TIMED_FORMAT "%s\t%lu\t%lu"
+#define TRAP_NULL_STRING(str) ((str) ? (str) : "<none>")
+
+typedef enum
+{
+ PROFILE_ATTRIBUTE_FLAG_SERIAL = 1,
+ PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL = 2,
+ PROFILE_ATTRIBUTE_FLAG_SENDER = 4,
+ PROFILE_ATTRIBUTE_FLAG_DESTINATION = 8,
+ PROFILE_ATTRIBUTE_FLAG_PATH = 16,
+ PROFILE_ATTRIBUTE_FLAG_INTERFACE = 32,
+ PROFILE_ATTRIBUTE_FLAG_MEMBER = 64,
+ PROFILE_ATTRIBUTE_FLAG_ERROR_NAME = 128
+} ProfileAttributeFlags;
+
+static void
+profile_print_with_attrs (const char *type, DBusMessage *message,
+ struct timeval *t, ProfileAttributeFlags attrs)
+{
+ printf (PROFILE_TIMED_FORMAT, type, t->tv_sec, t->tv_usec);
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_SERIAL)
+ printf ("\t%u", dbus_message_get_serial (message));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL)
+ printf ("\t%u", dbus_message_get_reply_serial (message));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_SENDER)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_sender (message)));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_DESTINATION)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_destination (message)));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_PATH)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_path (message)));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_INTERFACE)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_interface (message)));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_MEMBER)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_member (message)));
+
+ if (attrs & PROFILE_ATTRIBUTE_FLAG_ERROR_NAME)
+ printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_error_name (message)));
+
+ printf ("\n");
+}
+
+static void
+print_message_profile (DBusMessage *message)
+{
+ struct timeval t;
+
+ if (gettimeofday (&t, NULL) < 0)
+ {
+ printf ("un\n");
+ return;
+ }
+
+ switch (dbus_message_get_type (message))
+ {
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ profile_print_with_attrs ("mc", message, &t,
+ PROFILE_ATTRIBUTE_FLAG_SERIAL |
+ PROFILE_ATTRIBUTE_FLAG_SENDER |
+ PROFILE_ATTRIBUTE_FLAG_PATH |
+ PROFILE_ATTRIBUTE_FLAG_INTERFACE |
+ PROFILE_ATTRIBUTE_FLAG_MEMBER);
+ break;
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ profile_print_with_attrs ("mr", message, &t,
+ PROFILE_ATTRIBUTE_FLAG_SERIAL |
+ PROFILE_ATTRIBUTE_FLAG_DESTINATION |
+ PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ profile_print_with_attrs ("err", message, &t,
+ PROFILE_ATTRIBUTE_FLAG_SERIAL |
+ PROFILE_ATTRIBUTE_FLAG_DESTINATION |
+ PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
+ break;
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ profile_print_with_attrs ("sig", message, &t,
+ PROFILE_ATTRIBUTE_FLAG_SERIAL |
+ PROFILE_ATTRIBUTE_FLAG_PATH |
+ PROFILE_ATTRIBUTE_FLAG_INTERFACE |
+ PROFILE_ATTRIBUTE_FLAG_MEMBER);
+ break;
+ default:
+ printf (PROFILE_TIMED_FORMAT "\n", "tun", t.tv_sec, t.tv_usec);
+ break;
+ }
+}
+
+static DBusHandlerResult
+profile_filter_func (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ print_message_profile (message);
+
+ if (dbus_message_is_signal (message,
+ DBUS_INTERFACE_LOCAL,
+ "Disconnected"))
+ exit (0);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+usage (char *name, int ecode)
+{
+ fprintf (stderr, "Usage: %s [--system | --session | --address ADDRESS] [--monitor | --profile ] [watch expressions]\n", name);
+ exit (ecode);
+}
+
+static dbus_bool_t sigint_received = FALSE;
+
+static void
+sigint_handler (int signum)
+{
+ sigint_received = TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ DBusConnection *connection;
+ DBusError error;
+ DBusBusType type = DBUS_BUS_SESSION;
+ DBusHandleMessageFunction filter_func = monitor_filter_func;
+ char *address = NULL;
+
+ int i = 0, j = 0, numFilters = 0;
+ char **filters = NULL;
+
+ /* Set stdout to be unbuffered; this is basically so that if people
+ * do dbus-monitor > file, then send SIGINT via Control-C, they
+ * don't lose the last chunk of messages.
+ */
+ setvbuf (stdout, NULL, _IOLBF, 0);
+
+ for (i = 1; i < argc; i++)
+ {
+ char *arg = argv[i];
+
+ if (!strcmp (arg, "--system"))
+ type = DBUS_BUS_SYSTEM;
+ else if (!strcmp (arg, "--session"))
+ type = DBUS_BUS_SESSION;
+ else if (!strcmp (arg, "--address"))
+ {
+ if (i+1 < argc)
+ {
+ address = argv[i+1];
+ i++;
+ }
+ else
+ usage (argv[0], 1);
+ }
+ else if (!strcmp (arg, "--help"))
+ usage (argv[0], 0);
+ else if (!strcmp (arg, "--monitor"))
+ filter_func = monitor_filter_func;
+ else if (!strcmp (arg, "--profile"))
+ filter_func = profile_filter_func;
+ else if (!strcmp (arg, "--"))
+ continue;
+ else if (arg[0] == '-')
+ usage (argv[0], 1);
+ else {
+ numFilters++;
+ filters = (char **)realloc(filters, numFilters * sizeof(char *));
+ filters[j] = (char *)malloc((strlen(arg) + 1) * sizeof(char *));
+ snprintf(filters[j], strlen(arg) + 1, "%s", arg);
+ j++;
+ }
+ }
+
+ dbus_error_init (&error);
+
+ if (address != NULL)
+ {
+ connection = dbus_connection_open (address, &error);
+ if (connection)
+ {
+ if (!dbus_bus_register (connection, &error))
+ {
+ fprintf (stderr, "Failed to register connection to bus at %s: %s\n",
+ address, error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+ }
+ }
+ else
+ connection = dbus_bus_get (type, &error);
+ if (connection == NULL)
+ {
+ const char *where;
+ if (address != NULL)
+ where = address;
+ else
+ {
+ switch (type)
+ {
+ case DBUS_BUS_SYSTEM:
+ where = "system bus";
+ break;
+ case DBUS_BUS_SESSION:
+ where = "session bus";
+ break;
+ default:
+ where = "";
+ }
+ }
+ fprintf (stderr, "Failed to open connection to %s: %s\n",
+ where,
+ error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+
+ if (numFilters)
+ {
+ for (i = 0; i < j; i++)
+ {
+ dbus_bus_add_match (connection, filters[i], &error);
+ if (dbus_error_is_set (&error))
+ {
+ fprintf (stderr, "Failed to setup match \"%s\": %s\n",
+ filters[i], error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+ free(filters[i]);
+ }
+ }
+ else
+ {
+ dbus_bus_add_match (connection,
+ "type='signal'",
+ &error);
+ if (dbus_error_is_set (&error))
+ goto lose;
+ dbus_bus_add_match (connection,
+ "type='method_call'",
+ &error);
+ if (dbus_error_is_set (&error))
+ goto lose;
+ dbus_bus_add_match (connection,
+ "type='method_return'",
+ &error);
+ if (dbus_error_is_set (&error))
+ goto lose;
+ dbus_bus_add_match (connection,
+ "type='error'",
+ &error);
+ if (dbus_error_is_set (&error))
+ goto lose;
+ }
+
+ if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
+ fprintf (stderr, "Couldn't add filter!\n");
+ exit (1);
+ }
+
+ while (dbus_connection_read_write_dispatch(connection, -1))
+ ;
+ exit (0);
+ lose:
+ fprintf (stderr, "Error: %s\n", error.message);
+ exit (1);
+}
+
diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c
new file mode 100644
index 00000000..fac5cc1f
--- /dev/null
+++ b/tools/dbus-print-message.c
@@ -0,0 +1,407 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-print-message.h Utility function to print out a message
+ *
+ * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
+ * Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include "dbus-print-message.h"
+
+#include <stdlib.h>
+#include "config.h"
+
+static const char*
+type_to_name (int message_type)
+{
+ switch (message_type)
+ {
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ return "signal";
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ return "method call";
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ return "method return";
+ case DBUS_MESSAGE_TYPE_ERROR:
+ return "error";
+ default:
+ return "(unknown message type)";
+ }
+}
+
+#define INDENT 3
+
+static void
+indent (int depth)
+{
+ while (depth-- > 0)
+ printf (" "); /* INDENT spaces. */
+}
+
+static void
+print_hex (unsigned char *bytes, unsigned int len, int depth)
+{
+ int i, columns;
+
+ printf ("array of bytes [\n");
+
+ indent (depth + 1);
+
+ /* Each byte takes 3 cells (two hexits, and a space), except the last one. */
+ columns = (80 - ((depth + 1) * INDENT)) / 3;
+
+ if (columns < 8)
+ columns = 8;
+
+ i = 0;
+
+ while (i < len)
+ {
+ printf ("%02x", bytes[i]);
+ i++;
+
+ if (i != len)
+ {
+ if (i % columns == 0)
+ {
+ printf ("\n");
+ indent (depth + 1);
+ }
+ else
+ {
+ printf (" ");
+ }
+ }
+ }
+
+ printf ("\n");
+ indent (depth);
+ printf ("]\n");
+}
+
+#define DEFAULT_SIZE 100
+
+static void
+print_ay (DBusMessageIter *iter, int depth)
+{
+ /* Not using DBusString because it's not public API. It's 2009, and I'm
+ * manually growing a string chunk by chunk.
+ */
+ unsigned char *bytes = malloc (DEFAULT_SIZE + 1);
+ unsigned int len = 0;
+ unsigned int max = DEFAULT_SIZE;
+ dbus_bool_t all_ascii = TRUE;
+ int current_type;
+
+ while ((current_type = dbus_message_iter_get_arg_type (iter))
+ != DBUS_TYPE_INVALID)
+ {
+ unsigned char val;
+
+ dbus_message_iter_get_basic (iter, &val);
+ bytes[len] = val;
+ len++;
+
+ if (val < 32 || val > 126)
+ all_ascii = FALSE;
+
+ if (len == max)
+ {
+ max *= 2;
+ bytes = realloc (bytes, max + 1);
+ }
+
+ dbus_message_iter_next (iter);
+ }
+
+ if (all_ascii)
+ {
+ bytes[len] = '\0';
+ printf ("array of bytes \"%s\"\n", bytes);
+ }
+ else
+ {
+ print_hex (bytes, len, depth);
+ }
+
+ free (bytes);
+}
+
+static void
+print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth)
+{
+ do
+ {
+ int type = dbus_message_iter_get_arg_type (iter);
+
+ if (type == DBUS_TYPE_INVALID)
+ break;
+
+ indent(depth);
+
+ switch (type)
+ {
+ case DBUS_TYPE_STRING:
+ {
+ char *val;
+ dbus_message_iter_get_basic (iter, &val);
+ if (!literal)
+ printf ("string \"");
+ printf ("%s", val);
+ if (!literal)
+ printf ("\"\n");
+ break;
+ }
+
+ case DBUS_TYPE_SIGNATURE:
+ {
+ char *val;
+ dbus_message_iter_get_basic (iter, &val);
+ if (!literal)
+ printf ("signature \"");
+ printf ("%s", val);
+ if (!literal)
+ printf ("\"\n");
+ break;
+ }
+
+ case DBUS_TYPE_OBJECT_PATH:
+ {
+ char *val;
+ dbus_message_iter_get_basic (iter, &val);
+ if (!literal)
+ printf ("object path \"");
+ printf ("%s", val);
+ if (!literal)
+ printf ("\"\n");
+ break;
+ }
+
+ case DBUS_TYPE_INT16:
+ {
+ dbus_int16_t val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("int16 %d\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_UINT16:
+ {
+ dbus_uint16_t val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("uint16 %u\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("int32 %d\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("uint32 %u\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_INT64:
+ {
+ dbus_int64_t val;
+ dbus_message_iter_get_basic (iter, &val);
+#ifdef DBUS_INT64_PRINTF_MODIFIER
+ printf ("int64 %" DBUS_INT64_PRINTF_MODIFIER "d\n", val);
+#else
+ printf ("int64 (omitted)\n");
+#endif
+ break;
+ }
+
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t val;
+ dbus_message_iter_get_basic (iter, &val);
+#ifdef DBUS_INT64_PRINTF_MODIFIER
+ printf ("uint64 %" DBUS_INT64_PRINTF_MODIFIER "u\n", val);
+#else
+ printf ("uint64 (omitted)\n");
+#endif
+ break;
+ }
+
+ case DBUS_TYPE_DOUBLE:
+ {
+ double val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("double %g\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("byte %d\n", val);
+ break;
+ }
+
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t val;
+ dbus_message_iter_get_basic (iter, &val);
+ printf ("boolean %s\n", val ? "true" : "false");
+ break;
+ }
+
+ case DBUS_TYPE_VARIANT:
+ {
+ DBusMessageIter subiter;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ printf ("variant ");
+ print_iter (&subiter, literal, depth+1);
+ break;
+ }
+ case DBUS_TYPE_ARRAY:
+ {
+ int current_type;
+ DBusMessageIter subiter;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ current_type = dbus_message_iter_get_arg_type (&subiter);
+
+ if (current_type == DBUS_TYPE_BYTE)
+ {
+ print_ay (&subiter, depth);
+ break;
+ }
+
+ printf("array [\n");
+ while (current_type != DBUS_TYPE_INVALID)
+ {
+ print_iter (&subiter, literal, depth+1);
+
+ dbus_message_iter_next (&subiter);
+ current_type = dbus_message_iter_get_arg_type (&subiter);
+
+ if (current_type != DBUS_TYPE_INVALID)
+ printf (",");
+ }
+ indent(depth);
+ printf("]\n");
+ break;
+ }
+ case DBUS_TYPE_DICT_ENTRY:
+ {
+ DBusMessageIter subiter;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ printf("dict entry(\n");
+ print_iter (&subiter, literal, depth+1);
+ dbus_message_iter_next (&subiter);
+ print_iter (&subiter, literal, depth+1);
+ indent(depth);
+ printf(")\n");
+ break;
+ }
+
+ case DBUS_TYPE_STRUCT:
+ {
+ int current_type;
+ DBusMessageIter subiter;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ printf("struct {\n");
+ while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
+ {
+ print_iter (&subiter, literal, depth+1);
+ dbus_message_iter_next (&subiter);
+ if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
+ printf (",");
+ }
+ indent(depth);
+ printf("}\n");
+ break;
+ }
+
+ default:
+ printf (" (dbus-monitor too dumb to decipher arg type '%c')\n", type);
+ break;
+ }
+ } while (dbus_message_iter_next (iter));
+}
+
+void
+print_message (DBusMessage *message, dbus_bool_t literal)
+{
+ DBusMessageIter iter;
+ const char *sender;
+ const char *destination;
+ int message_type;
+
+ message_type = dbus_message_get_type (message);
+ sender = dbus_message_get_sender (message);
+ destination = dbus_message_get_destination (message);
+
+ if (!literal)
+ {
+ printf ("%s sender=%s -> dest=%s",
+ type_to_name (message_type),
+ sender ? sender : "(null sender)",
+ destination ? destination : "(null destination)");
+
+ switch (message_type)
+ {
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ printf (" serial=%u path=%s; interface=%s; member=%s\n",
+ dbus_message_get_serial (message),
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message));
+ break;
+
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ printf (" reply_serial=%u\n",
+ dbus_message_get_reply_serial (message));
+ break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+ printf (" error_name=%s reply_serial=%u\n",
+ dbus_message_get_error_name (message),
+ dbus_message_get_reply_serial (message));
+ break;
+
+ default:
+ printf ("\n");
+ break;
+ }
+ }
+
+ dbus_message_iter_init (message, &iter);
+ print_iter (&iter, literal, 1);
+ fflush (stdout);
+
+}
+
diff --git a/tools/dbus-print-message.h b/tools/dbus-print-message.h
new file mode 100644
index 00000000..26700d84
--- /dev/null
+++ b/tools/dbus-print-message.h
@@ -0,0 +1,31 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-print-message.h Utility function to print out a message
+ *
+ * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
+ * Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_PRINT_MESSAGE_H
+#define DBUS_PRINT_MESSAGE_H
+
+#include <stdio.h>
+#include <string.h>
+#include <dbus/dbus.h>
+
+void print_message (DBusMessage *message, dbus_bool_t literal);
+
+#endif /* DBUS_PRINT_MESSAGE_H */
diff --git a/tools/dbus-send.1 b/tools/dbus-send.1
new file mode 100644
index 00000000..4878c3d9
--- /dev/null
+++ b/tools/dbus-send.1
@@ -0,0 +1,95 @@
+.\"
+.\" dbus-send manual page.
+.\" Copyright (C) 2003 Red Hat, Inc.
+.\"
+.TH dbus-send 1
+.SH NAME
+dbus-send \- Send a message to a message bus
+.SH SYNOPSIS
+.PP
+.B dbus-send
+[\-\-system | \-\-session] [\-\-dest=NAME] [\-\-print-reply]
+[\-\-type=TYPE] <destination object path> <message name> [contents ...]
+
+.SH DESCRIPTION
+
+The \fIdbus-send\fP command is used to send a message to a D-Bus message
+bus. See http://www.freedesktop.org/software/dbus/ for more
+information about the big picture.
+
+.PP
+There are two well-known message buses: the systemwide message bus
+(installed on many systems as the "messagebus" service) and the
+per-user-login-session message bus (started each time a user logs in).
+The \-\-system and \-\-session options direct \fIdbus-send\fP to send
+messages to the system or session buses respectively. If neither is
+specified, \fIdbus-send\fP sends to the session bus.
+
+.PP
+Nearly all uses of \fIdbus-send\fP must provide the \-\-dest argument
+which is the name of a connection on the bus to send the message to. If
+\-\-dest is omitted, no destination is set.
+
+.PP
+The object path and the name of the message to send must always be
+specified. Following arguments, if any, are the message contents
+(message arguments). These are given as type-specified values and
+may include containers (arrays, dicts, and variants) as described below.
+
+.nf
+<contents> ::= <item> | <container> [ <item> | <container>...]
+<item> ::= <type>:<value>
+<container> ::= <array> | <dict> | <variant>
+<array> ::= array:<type>:<value>[,<value>...]
+<dict> ::= dict:<type>:<type>:<key>,<value>[,<key>,<value>...]
+<variant> ::= variant:<type>:<value>
+<type> ::= string | int16 | uint 16 | int32 | uint32 | int64 | uint64 | double | byte | boolean | objpath
+.fi
+
+D-Bus supports more types than these, but \fIdbus-send\fP currently
+does not. Also, \fIdbus-send\fP does not permit empty containers
+or nested containers (e.g. arrays of variants).
+
+.PP
+Here is an example invocation:
+.nf
+
+ dbus-send \-\-dest=org.freedesktop.ExampleName \\
+ /org/freedesktop/sample/object/name \\
+ org.freedesktop.ExampleInterface.ExampleMethod \\
+ int32:47 string:'hello world' double:65.32 \\
+ array:string:"1st item","next item","last item" \\
+ dict:string:int32:"one",1,"two",2,"three",3 \\
+ variant:int32:-8 \\
+ objpath:/org/freedesktop/sample/object/name
+
+.fi
+
+Note that the interface is separated from a method or signal
+name by a dot, though in the actual protocol the interface
+and the interface member are separate fields.
+
+.SH OPTIONS
+The following options are supported:
+.TP
+.I "--dest=NAME"
+Specify the name of the connection to receive the message.
+.TP
+.I "--print-reply"
+Block for a reply to the message sent, and print any reply received.
+.TP
+.I "--system"
+Send to the system message bus.
+.TP
+.I "--session"
+Send to the session message bus. (This is the default.)
+.TP
+.I "--type=TYPE"
+Specify "method_call" or "signal" (defaults to "signal").
+
+.SH AUTHOR
+dbus-send was written by Philip Blundell.
+
+.SH BUGS
+Please send bug reports to the D-Bus mailing list or bug tracker,
+see http://www.freedesktop.org/software/dbus/
diff --git a/tools/dbus-send.c b/tools/dbus-send.c
new file mode 100644
index 00000000..c9c9be27
--- /dev/null
+++ b/tools/dbus-send.c
@@ -0,0 +1,526 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-send.c Utility program to send messages from the command line
+ *
+ * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+
+#include "dbus-print-message.h"
+
+static const char *appname;
+
+static void
+usage (int ecode)
+{
+ fprintf (stderr, "Usage: %s [--help] [--system | --session | --address=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
+ exit (ecode);
+}
+
+static void
+append_arg (DBusMessageIter *iter, int type, const char *value)
+{
+ dbus_uint16_t uint16;
+ dbus_int16_t int16;
+ dbus_uint32_t uint32;
+ dbus_int32_t int32;
+ dbus_uint64_t uint64;
+ dbus_int64_t int64;
+ double d;
+ unsigned char byte;
+ dbus_bool_t v_BOOLEAN;
+
+ /* FIXME - we are ignoring OOM returns on all these functions */
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ byte = strtoul (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &byte);
+ break;
+
+ case DBUS_TYPE_DOUBLE:
+ d = strtod (value, NULL);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &d);
+ break;
+
+ case DBUS_TYPE_INT16:
+ int16 = strtol (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT16, &int16);
+ break;
+
+ case DBUS_TYPE_UINT16:
+ uint16 = strtoul (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT16, &uint16);
+ break;
+
+ case DBUS_TYPE_INT32:
+ int32 = strtol (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &int32);
+ break;
+
+ case DBUS_TYPE_UINT32:
+ uint32 = strtoul (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &uint32);
+ break;
+
+ case DBUS_TYPE_INT64:
+ int64 = strtoll (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &int64);
+ break;
+
+ case DBUS_TYPE_UINT64:
+ uint64 = strtoull (value, NULL, 0);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &uint64);
+ break;
+
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
+ break;
+
+ case DBUS_TYPE_OBJECT_PATH:
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &value);
+ break;
+
+ case DBUS_TYPE_BOOLEAN:
+ if (strcmp (value, "true") == 0)
+ {
+ v_BOOLEAN = TRUE;
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN);
+ }
+ else if (strcmp (value, "false") == 0)
+ {
+ v_BOOLEAN = FALSE;
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN);
+ }
+ else
+ {
+ fprintf (stderr, "%s: Expected \"true\" or \"false\" instead of \"%s\"\n", appname, value);
+ exit (1);
+ }
+ break;
+
+ default:
+ fprintf (stderr, "%s: Unsupported data type %c\n", appname, (char) type);
+ exit (1);
+ }
+}
+
+static void
+append_array (DBusMessageIter *iter, int type, const char *value)
+{
+ const char *val;
+ char *dupval = strdup (value);
+
+ val = strtok (dupval, ",");
+ while (val != NULL)
+ {
+ append_arg (iter, type, val);
+ val = strtok (NULL, ",");
+ }
+ free (dupval);
+}
+
+static void
+append_dict (DBusMessageIter *iter, int keytype, int valtype, const char *value)
+{
+ const char *val;
+ char *dupval = strdup (value);
+
+ val = strtok (dupval, ",");
+ while (val != NULL)
+ {
+ DBusMessageIter subiter;
+
+ dbus_message_iter_open_container (iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL,
+ &subiter);
+
+ append_arg (&subiter, keytype, val);
+ val = strtok (NULL, ",");
+ if (val == NULL)
+ {
+ fprintf (stderr, "%s: Malformed dictionary\n", appname);
+ exit (1);
+ }
+ append_arg (&subiter, valtype, val);
+
+ dbus_message_iter_close_container (iter, &subiter);
+ val = strtok (NULL, ",");
+ }
+ free (dupval);
+}
+
+static int
+type_from_name (const char *arg)
+{
+ int type;
+ if (!strcmp (arg, "string"))
+ type = DBUS_TYPE_STRING;
+ else if (!strcmp (arg, "int16"))
+ type = DBUS_TYPE_INT16;
+ else if (!strcmp (arg, "uint16"))
+ type = DBUS_TYPE_UINT16;
+ else if (!strcmp (arg, "int32"))
+ type = DBUS_TYPE_INT32;
+ else if (!strcmp (arg, "uint32"))
+ type = DBUS_TYPE_UINT32;
+ else if (!strcmp (arg, "int64"))
+ type = DBUS_TYPE_INT64;
+ else if (!strcmp (arg, "uint64"))
+ type = DBUS_TYPE_UINT64;
+ else if (!strcmp (arg, "double"))
+ type = DBUS_TYPE_DOUBLE;
+ else if (!strcmp (arg, "byte"))
+ type = DBUS_TYPE_BYTE;
+ else if (!strcmp (arg, "boolean"))
+ type = DBUS_TYPE_BOOLEAN;
+ else if (!strcmp (arg, "objpath"))
+ type = DBUS_TYPE_OBJECT_PATH;
+ else
+ {
+ fprintf (stderr, "%s: Unknown type \"%s\"\n", appname, arg);
+ exit (1);
+ }
+ return type;
+}
+
+int
+main (int argc, char *argv[])
+{
+ DBusConnection *connection;
+ DBusError error;
+ DBusMessage *message;
+ int print_reply;
+ int print_reply_literal;
+ int reply_timeout;
+ DBusMessageIter iter;
+ int i;
+ DBusBusType type = DBUS_BUS_SESSION;
+ const char *dest = NULL;
+ const char *name = NULL;
+ const char *path = NULL;
+ int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
+ const char *type_str = NULL;
+ const char *address = NULL;
+ int session_or_system = FALSE;
+
+ appname = argv[0];
+
+ if (argc < 3)
+ usage (1);
+
+ print_reply = FALSE;
+ print_reply_literal = FALSE;
+ reply_timeout = -1;
+
+ for (i = 1; i < argc && name == NULL; i++)
+ {
+ char *arg = argv[i];
+
+ if (strcmp (arg, "--system") == 0)
+ {
+ type = DBUS_BUS_SYSTEM;
+ session_or_system = TRUE;
+ }
+ else if (strcmp (arg, "--session") == 0)
+ {
+ type = DBUS_BUS_SESSION;
+ session_or_system = TRUE;
+ }
+ else if (strstr (arg, "--address") == arg)
+ {
+ address = strchr (arg, '=');
+
+ if (address == NULL)
+ {
+ fprintf (stderr, "\"--address=\" requires an ADDRESS\n");
+ usage (1);
+ }
+ else
+ {
+ address = address + 1;
+ }
+ }
+ else if (strncmp (arg, "--print-reply", 13) == 0)
+ {
+ print_reply = TRUE;
+ message_type = DBUS_MESSAGE_TYPE_METHOD_CALL;
+ if (*(arg + 13) != '\0')
+ print_reply_literal = TRUE;
+ }
+ else if (strstr (arg, "--reply-timeout=") == arg)
+ {
+ reply_timeout = strtol (strchr (arg, '=') + 1,
+ NULL, 10);
+ }
+ else if (strstr (arg, "--dest=") == arg)
+ dest = strchr (arg, '=') + 1;
+ else if (strstr (arg, "--type=") == arg)
+ type_str = strchr (arg, '=') + 1;
+ else if (!strcmp(arg, "--help"))
+ usage (0);
+ else if (arg[0] == '-')
+ usage (1);
+ else if (path == NULL)
+ path = arg;
+ else if (name == NULL)
+ name = arg;
+ else
+ usage (1);
+ }
+
+ if (name == NULL)
+ usage (1);
+
+ if (session_or_system &&
+ (address != NULL))
+ {
+ fprintf (stderr, "\"--address\" may not be used with \"--system\" or \"--session\"\n");
+ usage (1);
+ }
+
+ if (type_str != NULL)
+ {
+ message_type = dbus_message_type_from_string (type_str);
+ if (!(message_type == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+ message_type == DBUS_MESSAGE_TYPE_SIGNAL))
+ {
+ fprintf (stderr, "Message type \"%s\" is not supported\n",
+ type_str);
+ exit (1);
+ }
+ }
+
+ dbus_error_init (&error);
+
+ if (address != NULL)
+ {
+ connection = dbus_connection_open (address, &error);
+ }
+ else
+ {
+ connection = dbus_bus_get (type, &error);
+ }
+
+ if (connection == NULL)
+ {
+ fprintf (stderr, "Failed to open connection to \"%s\" message bus: %s\n",
+ (address != NULL) ? address :
+ ((type == DBUS_BUS_SYSTEM) ? "system" : "session"),
+ error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+
+ if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL)
+ {
+ char *last_dot;
+
+ last_dot = strrchr (name, '.');
+ if (last_dot == NULL)
+ {
+ fprintf (stderr, "Must use org.mydomain.Interface.Method notation, no dot in \"%s\"\n",
+ name);
+ exit (1);
+ }
+ *last_dot = '\0';
+
+ message = dbus_message_new_method_call (NULL,
+ path,
+ name,
+ last_dot + 1);
+ dbus_message_set_auto_start (message, TRUE);
+ }
+ else if (message_type == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ char *last_dot;
+
+ last_dot = strrchr (name, '.');
+ if (last_dot == NULL)
+ {
+ fprintf (stderr, "Must use org.mydomain.Interface.Signal notation, no dot in \"%s\"\n",
+ name);
+ exit (1);
+ }
+ *last_dot = '\0';
+
+ message = dbus_message_new_signal (path, name, last_dot + 1);
+ }
+ else
+ {
+ fprintf (stderr, "Internal error, unknown message type\n");
+ exit (1);
+ }
+
+ if (message == NULL)
+ {
+ fprintf (stderr, "Couldn't allocate D-Bus message\n");
+ exit (1);
+ }
+
+ if (dest && !dbus_message_set_destination (message, dest))
+ {
+ fprintf (stderr, "Not enough memory\n");
+ exit (1);
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+
+ while (i < argc)
+ {
+ char *arg;
+ char *c;
+ int type;
+ int secondary_type;
+ int container_type;
+ DBusMessageIter *target_iter;
+ DBusMessageIter container_iter;
+
+ type = DBUS_TYPE_INVALID;
+ arg = argv[i++];
+ c = strchr (arg, ':');
+
+ if (c == NULL)
+ {
+ fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
+ exit (1);
+ }
+
+ *(c++) = 0;
+
+ container_type = DBUS_TYPE_INVALID;
+
+ if (strcmp (arg, "variant") == 0)
+ container_type = DBUS_TYPE_VARIANT;
+ else if (strcmp (arg, "array") == 0)
+ container_type = DBUS_TYPE_ARRAY;
+ else if (strcmp (arg, "dict") == 0)
+ container_type = DBUS_TYPE_DICT_ENTRY;
+
+ if (container_type != DBUS_TYPE_INVALID)
+ {
+ arg = c;
+ c = strchr (arg, ':');
+ if (c == NULL)
+ {
+ fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
+ exit (1);
+ }
+ *(c++) = 0;
+ }
+
+ if (arg[0] == 0)
+ type = DBUS_TYPE_STRING;
+ else
+ type = type_from_name (arg);
+
+ if (container_type == DBUS_TYPE_DICT_ENTRY)
+ {
+ char sig[5];
+ arg = c;
+ c = strchr (c, ':');
+ if (c == NULL)
+ {
+ fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
+ exit (1);
+ }
+ *(c++) = 0;
+ secondary_type = type_from_name (arg);
+ sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+ sig[1] = type;
+ sig[2] = secondary_type;
+ sig[3] = DBUS_DICT_ENTRY_END_CHAR;
+ sig[4] = '\0';
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ sig,
+ &container_iter);
+ target_iter = &container_iter;
+ }
+ else if (container_type != DBUS_TYPE_INVALID)
+ {
+ char sig[2];
+ sig[0] = type;
+ sig[1] = '\0';
+ dbus_message_iter_open_container (&iter,
+ container_type,
+ sig,
+ &container_iter);
+ target_iter = &container_iter;
+ }
+ else
+ target_iter = &iter;
+
+ if (container_type == DBUS_TYPE_ARRAY)
+ {
+ append_array (target_iter, type, c);
+ }
+ else if (container_type == DBUS_TYPE_DICT_ENTRY)
+ {
+ append_dict (target_iter, type, secondary_type, c);
+ }
+ else
+ append_arg (target_iter, type, c);
+
+ if (container_type != DBUS_TYPE_INVALID)
+ {
+ dbus_message_iter_close_container (&iter,
+ &container_iter);
+ }
+ }
+
+ if (print_reply)
+ {
+ DBusMessage *reply;
+
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (connection,
+ message, reply_timeout,
+ &error);
+ if (dbus_error_is_set (&error))
+ {
+ fprintf (stderr, "Error %s: %s\n",
+ error.name,
+ error.message);
+ exit (1);
+ }
+
+ if (reply)
+ {
+ print_message (reply, print_reply_literal);
+ dbus_message_unref (reply);
+ }
+ }
+ else
+ {
+ dbus_connection_send (connection, message, NULL);
+ dbus_connection_flush (connection);
+ }
+
+ dbus_message_unref (message);
+
+ dbus_connection_unref (connection);
+
+ exit (0);
+}
diff --git a/tools/dbus-uuidgen.1 b/tools/dbus-uuidgen.1
new file mode 100644
index 00000000..480fd18f
--- /dev/null
+++ b/tools/dbus-uuidgen.1
@@ -0,0 +1,89 @@
+.\"
+.\" 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 or reads a universally unique ID.
+
+.PP
+Note that the D-Bus UUID has no relationship to RFC 4122 and does not generate
+UUIDs compatible with that spec. Many systems have a separate command
+for that (often called "uuidgen").
+
+.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 like this:
+.nf
+ dbus-uuidgen --ensure
+.fi
+
+.PP
+This will ensure that /var/lib/dbus/machine-id exists and has the uuid in it.
+It won't overwrite an existing uuid, since this id should remain fixed
+for a single machine until the next reboot at least.
+
+.PP
+The important properties of the machine UUID are that 1) it remains
+unchanged until the next reboot and 2) it is different for any two
+running instances of the OS kernel. That is, if two processes see the
+same UUID, they should also see the same shared memory, UNIX domain
+sockets, local X displays, localhost.localdomain resolution, process
+IDs, and so forth.
+
+.PP
+If you run \fIdbus-uuidgen\fP with no options it just prints a new uuid made
+up out of thin air.
+
+.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.
+
+.PP
+If you try to change an existing machine-id on a running system, it will
+probably result in bad things happening. Don't try to change this file. Also,
+don't make it the same on two different systems; it needs to be different
+anytime there are two different kernels running.
+
+.PP
+The UUID should be different on two different virtual machines,
+because there are two different kernels.
+
+.SH OPTIONS
+The following options are supported:
+.TP
+.I "--get[=FILENAME]"
+If a filename is not given, defaults to localstatedir/lib/dbus/machine-id
+(localstatedir is usually /var). 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 localstatedir/lib/dbus/machine-id
+(localstatedir is usually /var). 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.
+On success, prints no output.
+
+.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/
diff --git a/tools/dbus-uuidgen.c b/tools/dbus-uuidgen.c
new file mode 100644
index 00000000..c8ba1cf7
--- /dev/null
+++ b/tools/dbus-uuidgen.c
@@ -0,0 +1,161 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus-uuidgen.h>
+#include <dbus/dbus.h>
+
+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);
+}
+
+static dbus_bool_t
+get_arg (const char *arg,
+ const char *option,
+ const char **value_p)
+{
+ 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')
+ {
+ *value_p = fn;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ const char *filename;
+ dbus_bool_t ensure_uuid;
+ dbus_bool_t get_uuid;
+ DBusError error;
+
+ ensure_uuid = FALSE;
+ get_uuid = FALSE;
+
+ filename = NULL;
+
+ 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 and --ensure\n");
+ exit (1);
+ }
+
+ dbus_error_init (&error);
+
+ if (get_uuid || ensure_uuid)
+ {
+ char *uuid;
+ if (dbus_internal_do_not_use_get_uuid (filename, &uuid, ensure_uuid, &error))
+ {
+ if (get_uuid) /* print nothing on --ensure */
+ printf ("%s\n", uuid);
+ dbus_free (uuid);
+ }
+ }
+ else
+ {
+ char *uuid;
+ if (dbus_internal_do_not_use_create_uuid (&uuid))
+ {
+ printf ("%s\n", uuid);
+ dbus_free (uuid);
+ }
+ else
+ {
+ dbus_set_error (&error, DBUS_ERROR_NO_MEMORY, "No memory");
+ }
+ }
+
+ if (dbus_error_is_set (&error))
+ {
+ fprintf (stderr, "%s\n", error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+ else
+ {
+ exit (0);
+ }
+}
diff --git a/tools/run-with-tmp-session-bus.sh b/tools/run-with-tmp-session-bus.sh
new file mode 100755
index 00000000..982184a2
--- /dev/null
+++ b/tools/run-with-tmp-session-bus.sh
@@ -0,0 +1,76 @@
+#! /bin/bash
+
+SCRIPTNAME=$0
+WRAPPED_SCRIPT=$1
+shift
+
+die()
+{
+ if ! test -z "$DBUS_SESSION_BUS_PID" ; then
+ echo "killing message bus "$DBUS_SESSION_BUS_PID >&2
+ kill -9 $DBUS_SESSION_BUS_PID
+ fi
+ echo $SCRIPTNAME: $* >&2
+ exit 1
+}
+
+if test -z "$DBUS_TOP_BUILDDIR" ; then
+ die "Must set DBUS_TOP_BUILDDIR"
+fi
+
+## convenient to be able to ctrl+C without leaking the message bus process
+trap 'die "Received SIGINT"' INT
+
+CONFIG_FILE=./run-with-tmp-session-bus.conf
+SERVICE_DIR="$DBUS_TOP_BUILDDIR/test/data/valid-service-files"
+ESCAPED_SERVICE_DIR=`echo $SERVICE_DIR | sed -e 's/\//\\\\\\//g'`
+echo "escaped service dir is: $ESCAPED_SERVICE_DIR" >&2
+
+if test -z "$SOURCE_CONFIG_FILE"; then
+ SOURCE_CONFIG_FILE="$DBUS_TOP_BUILDDIR/bus/session.conf";
+fi
+## create a configuration file based on the standard session.conf
+cat $SOURCE_CONFIG_FILE | \
+ sed -e 's/<standard_session_servicedirs.*$/<servicedir>'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' | \
+ sed -e 's/<include.*$//g' \
+ > $CONFIG_FILE
+
+echo "Created configuration file $CONFIG_FILE" >&2
+
+if ! test -e "$DBUS_TOP_BUILDDIR"/bus/dbus-daemon ; then
+ die "$DBUS_TOP_BUILDDIR/bus/dbus-daemon does not exist"
+fi
+
+PATH="$DBUS_TOP_BUILDDIR"/bus:$PATH
+export PATH
+
+## the libtool script found by the path search should already do this, but
+LD_LIBRARY_PATH=$DBUS_TOP_BUILDDIR/dbus/.libs:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+unset DBUS_SESSION_BUS_ADDRESS
+unset DBUS_SESSION_BUS_PID
+
+echo "Running $DBUS_TOP_BUILDDIR/tools/dbus-launch --sh-syntax --config-file=$CONFIG_FILE" >&2
+
+DBUS_USE_TEST_BINARY=1
+export DBUS_USE_TEST_BINARY
+eval `$DBUS_TOP_BUILDDIR/tools/dbus-launch --sh-syntax --config-file=$CONFIG_FILE`
+
+if test -z "$DBUS_SESSION_BUS_PID" ; then
+ die "Failed to launch message bus for test script to run"
+fi
+
+echo "Started bus pid $DBUS_SESSION_BUS_PID at $DBUS_SESSION_BUS_ADDRESS" >&2
+
+# Execute wrapped script
+echo "Running $WRAPPED_SCRIPT $@" >&2
+$WRAPPED_SCRIPT "$@" || die "script \"$WRAPPED_SCRIPT\" failed"
+
+kill -TERM $DBUS_SESSION_BUS_PID || die "Message bus vanished! should not have happened" && echo "Killed daemon $DBUS_SESSION_BUS_PID" >&2
+
+sleep 2
+
+## be sure it really died
+kill -9 $DBUS_SESSION_BUS_PID > /dev/null 2>&1 || true
+
+exit 0