diff -urN dmd--0.7/ChangeLog dmd--0.5/ChangeLog
--- dmd--0.7/ChangeLog	2003-03-23 16:23:50.000000000 +0100
+++ dmd--0.5/ChangeLog	2003-05-01 22:23:19.000000000 +0200
@@ -1,16 +1,325 @@
+2003-05-01  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (stop.<service>): Ignore the result of the
+	user-defined stop code.  Set the `running' slot of the service to
+	`#f' in any case.
+	(<service>): Adopted semantics of `stop' slot.
+
+	* support.scm (opt-lambda): New macro.
+	* self.scm (persistency): Use it.
+	* service.scm (make-kill-destructor): Likewise.
+
+2003-04-27  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* self.scm (enable-persistency): Renamed to ...
+	(persistency): ... this.  New action.
+	(disable-persistency): Renamed to ...
+	(no-persistency): ... this.  New action.
+
+2003-04-25  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (label): New macro.
+	* self.scm (enable-persistency): Use `label' and `case-lambda'
+	instead of `lambda*'.
+	* dmd.scm: Don't use module `(ice-9 optargs)'.
+
+	* service.scm (doc.<service>): Don't break if given action is not
+	provided by the service.
+	(first-running): Simplify.
+
+2003-04-24  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* self.scm (enable-persistency): New optional argument `file' for
+	setting the persistency state file.
+	* dmd.scm: Use module `(ice-9 optargs)'.
+
+2003-04-21  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* dmd.scm (process-command): Fix handling of `dmd-status'.  Also
+	cleaned up the code.
+	* service.scm (handle-unknown): New procedure.
+
+	(make-actions): Bugfix: Exchange position of procedure and
+	docstring in the created pairs.
+
+	* self.scm (detailed-status): Updated to change of Apr 10.
+
+	* service.scm (<service>): Default init value of `start' slot is
+	now a procedure that takes no arguments.  Similar for `stop': It
+	accepts only one argument now.
+
+	* examples/_unknown.scm (compose): New procedure.
+	(unknown-service): Use it in the `start' action.
+	(look-for-service): Cleaned up.
+
+2003-04-20  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (lookup-running): New procedure.
+	(depends-resolved?.<service>): Use it.
+	(launch-service): Likewise.
+	(stop.<symbol>): Likewise.
+	(action.<symbol>): Likewise.
+
+	(status.<symbol>): Show status of running service, if any.
+	Otherwise, show status of all who provide the symbol.  Also
+	display `dmd-status' only if service does not provide a `status'
+	action.
+
+	(lookup-running-or-providing): New procedure.
+	(action.<symbol>): Use it.
+	(status.<symbol>): Likewise.
+
+	(<service>): Field `actions' is a list now instead of a hash.
+	(action:name): New procedure.
+	(action:proc): New procedure.
+	(action:doc): New procedure.
+	(lookup-action.<service>): New method.
+	(defines-action?.<service>): Adopted to the new structure of the
+	`actions' slot.
+	(actions-list.<service>): Likewise.
+	(action.<service>): Likewise.
+	(doc.<service>): Likewise.
+	(make-actions): Made the docstring optional.  Also, adopted to new
+	structure of `actions' slot of `<service>'.
+
+	(action.<service>): Show `dmd-status' in the default
+	implementation of `status'.
+	(status.<symbol>): Removed.
+	* dmd.scm (process-command): Don't handle `status' action here.
+
+2003-04-18  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (caught-error): Handle `wrong-number-of-args'
+	specially.
+
+	* service.scm (action.<service>): Check whether the number of args
+	is ok.  Display a useful message if not.
+	* support.scm (can-apply?): New procedure.
+
+2003-04-17  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	(stop.<service>): If the service is respawnable, still set its
+	running slot to `#f' before calling the destructor, but do call
+	the destructor with the original value of the slot.
+
+	* examples/_unknown.scm (look-for-service): Additional (optional)
+	argument: A predicate that a service must satisfy.
+	(unknown-service): Look for running or non-running services first,
+	whichever makes more sense in the particular case.
+
+2003-04-16  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (<service>): Renamed slot `extra-actions' to
+	`actions'.
+	(defines-extra-action?.<service>): Renamed to ...
+	(defines-action?.<service>): ... this.  All callers changed.
+	(extra-action.<service>): Renamed to ...
+	(action.<service>): ... this.  All callers changed.
+	(extra-action.<symbol>): Renamed to ...
+	(action.<symbol>): ... this.  All callers changed.
+	(make-extra-actions): Renamed to ...
+	(make-actions): ... this.  All callers changed.
+
+	(make-forkexec-constructor): Use the arguments given to us, not
+	those given to the created procedure.
+
+2003-04-13  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (status.<symbol>): Implement.
+
+	* Makefile.am (EXTRA_DIST): Add file `QUESTIONS'.
+
+2003-04-12  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (extra-action.<service>): Handle `status' default
+	action, but do nothing in its implementation.
+	(status.<symbol>): New method.
+	* dmd.scm (process-command): Handle `dmd-status' and `status'.
+
+2003-04-10  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (default-display-status.<service>): Renamed to ...
+	(dmd-status.<service>): ... this.  New procedure.
+	(extra-action.<service>): Don't provide a default implementation
+	of `status' here.
+
+2003-04-09  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* args.scm (process-args): Make `--file -' and `-f -' work like
+	`--file=-' and `-f-', repectively.
+	* dmd.scm (main): Use `-' instead of `none' as file name to
+	specify for readings commands from stdin (`--socket').
+
+2003-04-08  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* NEWS: Forked off version -0.6.
+
+2003-04-08  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (extra-action.<symbol>): Prevent arguments from
+	getting lost for the `doc' action.
+	(doc.<service>): Make it work at all by using symbols instead of
+	strings in the `case' structure.
+
+2003-04-07  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* examples/_unknown.scm (differs-in-case?): Renamed to ...
+	(differs-only-in-case?): ... this.  New procedure.  All callers
+	changed.
+
+	* service.scm (<service>): Every value in the `extra-actions' hash
+	now consists of a pair with the procedure in the CAR and the
+	docstring in the CDR.
+	(extra-action.<service>): Adopted to new structure of the
+	`extra-actions' slot.
+	(make-extra-actions): Likewise.
+	(doc.<service>): Display docstring on request.
+
+	* support.scm (split-case): Removed.
+	* service.scm (doc.<service>): Don't use `split-case' anymore.
+
+2003-03-28  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (make-childexec-constructor): Renamed to ...
+	(make-forkexec-constructor): ... this.  New procedure.
+
+	(make-kill-destructor): Default to SIGTERM.
+	* dmd.scm: Use module `(srfi srfi-16)'.
+
+2003-03-25  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* comm.scm (terminatimg-string): Moved out of dmd specific code,
+	as it is also used by deco.
+
 2003-03-23  Wolfgang Jährling  <wolfgang@pro-linux.de>
 
-	* service.scm (make-childexec-constructor): Accept arguments, but
-	ignore them for now.
+	* examples/_unknown.scm (look-for-service): New procedure.
+	(unknown-service): New extra-actions `stop' and `extra-action'.
+	Let `start' use `look-for-service'.
+
+	* service.scm (register-services): Verfify that canonical names
+	are actually canonical.
+
+	(make-childexec-constructor): Accept arguments, but ignore them.
 	(make-kill-destructor): Likewise.
 	(make-system-constructor): Likewise.
 	(make-system-destructor): Likewise.
 	(make-init.d-service): Updated to use the new names of the
 	procedures.  This should have been done *much* earlier.
 
+	(extra-action.<symbol>): Actually make the ``unknown service''
+	feature work.
+
+2003-03-15  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* dmd.scm: Use module `(ice-9 readline)'.
+	(main): Enable readline if we read commands from stdin
+	and it is a non-dumb terminal.  Exit on `C-d'.
+
+2003-03-12  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* service.scm (conflicts-with.<service>): Cleaned up.
+	(find-running): Renamed to ...
+	(first-running): ... this.  New procedure.  All callers changed.
+
+2003-03-09  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* configure.in: Check for version of Guile being at least 1.5.x.
+
+2003-03-08  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* examples/_unknown.scm: New file.
+	(lacks-char-from?): New procedure.
+	(differs-by-missing-char?): New procedure.
+	(differs-by-switched-chars?): New procedure.
+	(differs-by-one-char?): New procedure.
+	(differs-in-case?): New procedure.
+	(similar?): New procedure.
+	(unknown): New service.
+	* examples/Makefile.am (EXTRA_DIST): Add the new file.
+
+2003-03-02  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (without-system-error): Renamed to ...
+	(catch-system-error): ... this.  New macro.  All callers changed.
+	(local-output): Don't send data to deco.
+	(extra-output-sender-enabled): Removed.
+	(without-extra-output): Removed (new implementation in comm.scm).
+	* comm.scm (without-extra-output): New macro.
+	(dmd-output-port): Send data to deco.  Buffer the output for the
+	logfile line-wise.
+	* deco.scm (main): Don't display additional newlines.
+
+	* support.scm (extra-output-sender): Moved to ...
+	* comm.scm (extra-output-sender): ... here.
+	* support.scm (open-extra-sender): Moved to ...
+	* comm.scm (open-extra-sender): ... here.
+	* support.scm (close-extra-sender): Moved to ...
+	* comm.scm (close-extra-sender): ... here.
+	* support.scm (terminating-string): Moved to ...
+	* comm.scm (terminating-string): ... here.
+
+2003-02-25  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (display-version): Display stuff directly.
+	* config.scm.in (banner): Removed.
+
+	* support.scm (local-output): Don't do logging here anymore.
+	(real-output-port, void-output-port): Removed.
+	(log-output-port): Moved to ...
+	* comm.scm (log-output-port): ... here.  Conditional for dmd.
+	(dmd-output-port): Do logging here now.
+
+	* support.scm (without-extra-output): When catching an error, set
+	`extra-output-sender-enabled' to `#t', not to `#f'.
+
+2003-02-23  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (begin-dmd): New macro.
+	* comm.scm (dmd-output-port): Define only for dmd, not for deco.
+	(original-output-port): Likewise.
+	(silent): Likewise.
+	(be-silent, be-verbose): Likewise.
+
+	* support.scm (verify-dir): Code cleanup.
+
+	* service.scm (start.<service>): Simplified.  The different cond
+	clauses don't need to give a return value anyway, so these got
+	removed.
+
+	* self.scm (cd): New extra-action for dmd.
+
+2003-02-22  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* support.scm (be-silent, be-verbose): Removed.
+	* comm.scm (original-output-port): New variable.
+	(dmd-output-port): New variable.  Use it as current output port.
+	(silent): New variable.
+	(be-silent, be-verbose): New procedures.
+
+2003-02-21  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* dmd.scm (process-command): Don't handle `list-actions' here.
+	* service.scm (extra-action.<service>): Don't handle `doc' here.
+	(extra-action.<symbol>): Handle both of them here instead.
+	(doc.<service>): New method.
+	(display-extra-actions.<symbol>): Removed.
+	* support.scm (split-case): New macro.
+
+2003-02-20  Wolfgang Jährling  <wolfgang@pro-linux.de>
+
+	* self.scm (dmd-service): Added docstrings for the service and all
+	its extra-actions.
+	* service.scm (make-extra-actions): Accept docstring argument.  It
+	gets ignored for now.  Also, made code more readable by using the
+	extended `for-each' from SRFI-1.
+	(<service>): New slot `docstring'.
+	(extra-action.<service>): Default action takes arguments, new
+	handled action `doc'.
+
 2003-02-20  Wolfgang Jährling  <wolfgang@pro-linux.de>
 
-	* NEWS: Forked off version -0.6
+	* NEWS: Forked off version -0.7
 
 2003-02-17  Wolfgang Jährling  <wolfgang@pro-linux.de>
 
@@ -234,7 +543,8 @@
 	* examples/README: New file.
 	* examples/Makefile.am (EXTRA_DIST): Add it.
 
-	* service.scm (make-service-group): New macro.
+	* service.scm (make-service-group): New macro.  Suggested by
+	Alfred M. Szmidt <ams@kemisten.nu>.
 
 	* support.scm (define-simple-syntax): New macro.  All callers of
 	define-syntax changed to use this instead.
diff -urN dmd--0.7/Makefile.am dmd--0.5/Makefile.am
--- dmd--0.7/Makefile.am	2002-10-12 15:27:43.000000000 +0200
+++ dmd--0.5/Makefile.am	2003-04-13 12:22:35.000000000 +0200
@@ -1,5 +1,5 @@
 # Makefile.am -- How to build and install dmd.
-# Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+# Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 #
 # This is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
 SUBDIRS = examples utils
 
 # Things not automatically included in the distribution.
-EXTRA_DIST = $(dmd_data) $(templates)
+EXTRA_DIST = $(dmd_data) $(templates) QUESTIONS
 
 # Create the directory for the sockets.
 install-data-local:
diff -urN dmd--0.7/Makefile.in dmd--0.5/Makefile.in
--- dmd--0.7/Makefile.in	2002-10-12 15:41:04.000000000 +0200
+++ dmd--0.5/Makefile.in	2003-05-01 22:40:30.000000000 +0200
@@ -15,7 +15,7 @@
 @SET_MAKE@
 
 # Makefile.am -- How to build and install dmd.
-# Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+# Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 #
 # This is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -84,6 +84,12 @@
 AMTAR = @AMTAR@
 AWK = @AWK@
 DEPDIR = @DEPDIR@
+GUILE = @GUILE@
+GUILE_CFLAGS = @GUILE_CFLAGS@
+GUILE_CONFIG = @GUILE_CONFIG@
+GUILE_LDFLAGS = @GUILE_LDFLAGS@
+GUILE_SITE = @GUILE_SITE@
+GUILE_TOOLS = @GUILE_TOOLS@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 PACKAGE = @PACKAGE@
 STRIP = @STRIP@
@@ -108,7 +114,7 @@
 SUBDIRS = examples utils
 
 # Things not automatically included in the distribution.
-EXTRA_DIST = $(dmd_data) $(templates)
+EXTRA_DIST = $(dmd_data) $(templates) QUESTIONS
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
diff -urN dmd--0.7/NEWS dmd--0.5/NEWS
--- dmd--0.7/NEWS	2003-02-17 18:02:10.000000000 +0100
+++ dmd--0.5/NEWS	2003-05-01 10:53:30.000000000 +0200
@@ -1,3 +1,26 @@
+Version -0.5
+
+	* dmd: `--socket=-' instead of `--socket=none'.
+	* Renamed `extra-action' to plain `action'.
+	* The result of user-defined stop code is ignored now.
+	* New action for all services: `dmd-status'.
+	* Distribution contains file `QUESTIONS'.
+	* Improved the `unknown' service implementation in `examples/'.
+	* Number of args given to actions is verified.
+	* Made docstrings for actions optional.
+	* Renamed `{en,dis}able-persistency' to `{,no-}persistency'.
+	* Can pass file name to dmd action `persistency'.
+
+Version -0.6
+
+	* New action `doc' for displaying documentation.
+	* `list-actions' is a sub-action of `doc' now.
+	* New action `cd' for dmd, useful with `--socket=none'.
+	* Distribution contains example for an `unknown' service.
+	* At configure time, dmd checks for a Guile installation.
+	* Enable readline on `--socket=none' and non-dumb terminal.
+	* Startup time finally became completely unacceptable. :-)
+
 Version -0.7
 
 	* Can fork into background via dmd extra-action `daemonize'.
diff -urN dmd--0.7/QUESTIONS dmd--0.5/QUESTIONS
--- dmd--0.7/QUESTIONS	1970-01-01 01:00:00.000000000 +0100
+++ dmd--0.5/QUESTIONS	2003-04-21 14:16:05.000000000 +0200
@@ -0,0 +1,25 @@
+Open questions about dmd
+=-=-=-=-=-=-=-=-=-=-=-=-
+
+- Do we need a `requests' field for services?  Service-symbols
+  specified there would be started like requirements, but if starting
+  all services providing it would fail, we could continue anyway.
+  This sounds nice, but it can easiely be emulated by adding to the
+  `start' code something like:
+
+    (for-each start '(service1 service2))
+
+  Since this is so simple, I wonder if this functionality is that
+  commonly needed that it is worth adding it.  If desired, it would be
+  trivial to implement if we don't consider that we might get into
+  trouble due to conflicts of these services with other services we
+  need to start.
+
+- Do we need a field for services that specifies the global startup
+  order, which has a smaller priority than dependencies?  This is
+  implemented in Darwins init system and was requested for dmd, but I
+  have no idea what that should be good for.  If desired, it would
+  probably not be extremely hard to hack it into dmd.  However, a
+  better solution might be soft dependencies: "If we start both FOO
+  and BAR, start FOO first."
+
diff -urN dmd--0.7/README dmd--0.5/README
--- dmd--0.7/README	2003-01-01 16:14:05.000000000 +0100
+++ dmd--0.5/README	2003-05-01 11:22:44.000000000 +0200
@@ -2,25 +2,27 @@
 
 ** What is `dmd'?
 
-It is a service manager.  That is, on systems which are similar to
-Unix (e.g. GNU/Linux), it is a replacement for the part of the `init'
-program that manages runlevels and such.  On the GNU system, it is a
-replacement for `/sbin/init', but not for `/hurd/init'.
+The dmd program is a ``Daemon managing Daemons'' (or maybe a
+``Daemons-managing Daemon''?), i.e. a service manager, that is written
+in Guile, the extension language of the GNU project.  It provides a
+replacement for the service-managing capabillities of SysV-init (or
+any other init) with a both powerfull and beautiful dependency-based
+system with a convenient interface.  It is intended for use on
+GNU/Hurd, but it is supposed to work on every POSIX-like system where
+Guile is available.  In particular, it has been tested on GNU/Linux.
 
 ** Requirements
 
 This program requires Guile (the GNU Ubiquitous Intelligent Language
-for Extension), version 1.6.  It uses GOOPS, but as GOOPS is part of
-Guile, a normal Guile installation is sufficient.
-
-It is intended for use on GNU/Linux and GNU, but is likely to also
-work elsewhere.
+for Extension), version 1.6.x.  It uses GOOPS, but as GOOPS is part of
+Guile, a normal Guile installation is sufficient.  It also uses
+readline, though it does not really depend on it.
 
 ** Getting started
 
 Despite the fact that this program is written in an interpreted
 language, you can install this program like all programs that use
-autoconf, but the recommended way is:
+autoconf, but the recommended way in this case is:
 
   ./configure --prefix= --datadir=/usr/share
   make
@@ -34,7 +36,8 @@
 Detailed instructions on installing dmd are available in the file
 `INSTALL'.  A list of user-visible changes between releases can be
 found in the file `NEWS'.  Detailed information about changes on the
-source code level are listed in `ChangeLog'.
+source code level are listed in `ChangeLog'.  Open issues on which I
+would like to receive comments are explained in the file `QUESTIONS'.
 
 A list of people who can be considered maintainers of this software is
 available in the file `AUTHORS'.  A list of people who have been
@@ -49,12 +52,10 @@
 
 ** Bugs and Limitations
 
-There is no localization done yet.
-
-Code from the user configuration is allowed to mess up everything.
-
-Runlevels do not work yet.
-
-It is hard to setup currently.
+There is no localization done yet.  Code from the user configuration
+is allowed to mess up everything.  Runlevels do not work yet.  It is
+hard to setup currently.  A few bugs are already marked in the source
+code.
 
-Send bug reports to <wolfgang@pro-linux.de>.
+Send bug reports to  <wolfgang@pro-linux.de>
+              or to  <wolfgang.jaehrling@wt-ausbilder.de>.
diff -urN dmd--0.7/aclocal.m4 dmd--0.5/aclocal.m4
--- dmd--0.7/aclocal.m4	2002-10-12 15:41:02.000000000 +0200
+++ dmd--0.5/aclocal.m4	2003-04-08 17:08:57.000000000 +0200
@@ -756,3 +756,166 @@
 Usually this means the macro was only invoked conditionally.])
 fi])])
 
+
+
+
+
+# GUILE_PROGS -- set paths to Guile interpreter, config and tool programs
+#
+# Usage: GUILE_PROGS
+#
+# This macro looks for programs @code{guile}, @code{guile-config} and
+# @code{guile-tools}, and sets variables @var{GUILE}, @var{GUILE_CONFIG} and
+# @var{GUILE_TOOLS}, to their paths, respectively.  If either of the first two
+# is not found, signal error.
+#
+# The variables are marked for substitution, as by @code{AC_SUBST}.
+#
+AC_DEFUN([GUILE_PROGS],
+ [AC_PATH_PROG(GUILE,guile)
+  if test "$GUILE" = "" ; then
+      AC_MSG_ERROR([guile required but not found])
+  fi
+  AC_SUBST(GUILE)
+  AC_PATH_PROG(GUILE_CONFIG,guile-config)
+  if test "$GUILE_CONFIG" = "" ; then
+      AC_MSG_ERROR([guile-config required but not found])
+  fi
+  AC_SUBST(GUILE_CONFIG)
+  AC_PATH_PROG(GUILE_TOOLS,guile-tools)
+  AC_SUBST(GUILE_TOOLS)
+ ])
+
+# GUILE_FLAGS -- set flags for compiling and linking with Guile
+#
+# Usage: GUILE_FLAGS
+#
+# This macro runs the @code{guile-config} script, installed with Guile, to
+# find out where Guile's header files and libraries are installed.  It sets
+# two variables, @var{GUILE_CFLAGS} and @var{GUILE_LDFLAGS}.
+#
+# @var{GUILE_CFLAGS}: flags to pass to a C or C++ compiler to build code that
+# uses Guile header files.  This is almost always just a @code{-I} flag.
+#
+# @var{GUILE_LDFLAGS}: flags to pass to the linker to link a program against
+# Guile.  This includes @code{-lguile} for the Guile library itself, any
+# libraries that Guile itself requires (like -lqthreads), and so on.  It may
+# also include a @code{-L} flag to tell the compiler where to find the
+# libraries.
+#
+# The variables are marked for substitution, as by @code{AC_SUBST}.
+#
+AC_DEFUN([GUILE_FLAGS],
+ [AC_REQUIRE([GUILE_PROGS])dnl
+  AC_MSG_CHECKING([libguile compile flags])
+  GUILE_CFLAGS="`$GUILE_CONFIG compile`"
+  AC_MSG_RESULT([$GUILE_CFLAGS])
+  AC_MSG_CHECKING([libguile link flags])
+  GUILE_LDFLAGS="`$GUILE_CONFIG link`"
+  AC_MSG_RESULT([$GUILE_LDFLAGS])
+  AC_SUBST(GUILE_CFLAGS)
+  AC_SUBST(GUILE_LDFLAGS)
+ ])
+
+# GUILE_SITE_DIR -- find path to Guile "site" directory
+#
+# Usage: GUILE_SITE_DIR
+#
+# This looks for Guile's "site" directory, usually something like
+# PREFIX/share/guile/site, and sets var @var{GUILE_SITE} to the path.
+# Note that the var name is different from the macro name.
+#
+# The variable is marked for substitution, as by @code{AC_SUBST}.
+#
+AC_DEFUN([GUILE_SITE_DIR],
+ [AC_REQUIRE([GUILE_PROGS])dnl
+  AC_MSG_CHECKING(for Guile site directory)
+  GUILE_SITE=`[$GUILE_CONFIG] info pkgdatadir`/site
+  AC_MSG_RESULT($GUILE_SITE)
+  AC_SUBST(GUILE_SITE)
+ ])
+
+# GUILE_CHECK -- evaluate Guile Scheme code and capture the return value
+#
+# Usage: GUILE_CHECK_RETVAL(var,check)
+#
+# @var{var} is a shell variable name to be set to the return value.
+# @var{check} is a Guile Scheme expression, evaluated with "$GUILE -c", and
+#    returning either 0 or non-#f to indicate the check passed.
+#    Non-0 number or #f indicates failure.
+#    Avoid using the character "#" since that confuses autoconf.
+#
+AC_DEFUN([GUILE_CHECK],
+ [AC_REQUIRE([GUILE_PROGS])
+  $GUILE -c "$2" > /dev/null 2>&1
+  $1=$?
+ ])
+
+# GUILE_MODULE_CHECK -- check feature of a Guile Scheme module
+#
+# Usage: GUILE_MODULE_CHECK(var,module,featuretest,description)
+#
+# @var{var} is a shell variable name to be set to "yes" or "no".
+# @var{module} is a list of symbols, like: (ice-9 common-list).
+# @var{featuretest} is an expression acceptable to GUILE_CHECK, q.v.
+# @var{description} is a present-tense verb phrase (passed to AC_MSG_CHECKING).
+#
+AC_DEFUN([GUILE_MODULE_CHECK],
+         [AC_MSG_CHECKING([if $2 $4])
+	  GUILE_CHECK($1,(use-modules $2) (exit ((lambda () $3))))
+	  if test "$$1" = "0" ; then $1=yes ; else $1=no ; fi
+          AC_MSG_RESULT($$1)
+         ])
+
+# GUILE_MODULE_AVAILABLE -- check availability of a Guile Scheme module
+#
+# Usage: GUILE_MODULE_AVAILABLE(var,module)
+#
+# @var{var} is a shell variable name to be set to "yes" or "no".
+# @var{module} is a list of symbols, like: (ice-9 common-list).
+#
+AC_DEFUN([GUILE_MODULE_AVAILABLE],
+         [GUILE_MODULE_CHECK($1,$2,0,is available)
+         ])
+
+# GUILE_MODULE_REQUIRED -- fail if a Guile Scheme module is unavailable
+#
+# Usage: GUILE_MODULE_REQUIRED(symlist)
+#
+# @var{symlist} is a list of symbols, WITHOUT surrounding parens,
+# like: ice-9 common-list.
+#
+AC_DEFUN([GUILE_MODULE_REQUIRED],
+         [GUILE_MODULE_AVAILABLE(ac_guile_module_required, ($1))
+          if test "$ac_guile_module_required" = "no" ; then
+              AC_MSG_ERROR([required guile module not found: ($1)])
+          fi
+         ])
+
+# GUILE_MODULE_EXPORTS -- check if a module exports a variable
+#
+# Usage: GUILE_MODULE_EXPORTS(var,module,modvar)
+#
+# @var{var} is a shell variable to be set to "yes" or "no".
+# @var{module} is a list of symbols, like: (ice-9 common-list).
+# @var{modvar} is the Guile Scheme variable to check.
+#
+AC_DEFUN([GUILE_MODULE_EXPORTS],
+ [GUILE_MODULE_CHECK($1,$2,$3,exports `$3')
+ ])
+
+# GUILE_MODULE_REQUIRED_EXPORT -- fail if a module doesn't export a variable
+#
+# Usage: GUILE_MODULE_REQUIRED_EXPORT(module,modvar)
+#
+# @var{module} is a list of symbols, like: (ice-9 common-list).
+# @var{modvar} is the Guile Scheme variable to check.
+#
+AC_DEFUN([GUILE_MODULE_REQUIRED_EXPORT],
+ [GUILE_MODULE_EXPORTS(guile_module_required_export,$1,$2)
+  if test "$guile_module_required_export" = "no" ; then
+      AC_MSG_ERROR([module $1 does not export $2; required])
+  fi
+ ])
+
+
diff -urN dmd--0.7/args.scm dmd--0.5/args.scm
--- dmd--0.7/args.scm	2002-12-28 12:23:59.000000000 +0100
+++ dmd--0.5/args.scm	2003-04-09 23:03:35.000000000 +0200
@@ -1,5 +1,5 @@
 ;; args.scm -- Command line argument handling.
-;; Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;;
 ;; This is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -35,8 +35,8 @@
 	       #:init-form (l10n "undocumented option"))
   ;; Specifies whether the procedure in the `action' slot takes an
   ;; argument.  If this is the case, it will be called with the
-  ;; argument specified on the command line.  If there was none
-  ;; specified, the procedure will be called with `#f'.
+  ;; argument specified on the command line (If there was none
+  ;; specified, the procedure will be called with `#f').
   (takes-arg? #:init-keyword #:takes-arg?
 	      #:getter takes-arg?
 	      #:init-value #f)
@@ -63,7 +63,7 @@
 		 (if (optional-arg? obj) "[" "")
 		 (if (takes-arg? obj)
 		     (string-append "=" (slot-ref obj 'arg-name))
-		     "")
+		   "")
 		 (if (optional-arg? obj) "]" "")))
 
 (define-method (display-doc (obj <option>))
@@ -104,7 +104,7 @@
 			     (and (string-prefix? name (long option))
 				  (if abbrev-for
 				      (set! abbrev-for #t)
-				      (set! abbrev-for option))))
+				    (set! abbrev-for option))))
 			   options)
 		 abbrev-for))))
 
@@ -153,10 +153,10 @@
 						  (arg-name opt)
 						  (if opt-arg? "]" "")
 						  "]")))
-					 (set! no-arg
-					       (string-append
-						no-arg
-						(string (short opt)))))))
+				       (set! no-arg
+					     (string-append
+					      no-arg
+					      (string (short opt)))))))
 			      (for-each add-text options)
 			      (set! no-arg (string-append no-arg "]"))
 			      (display no-arg)
@@ -206,7 +206,7 @@
 	     (apply (action option)
 		    (if (takes-arg? option)
 			(cons param '())
-			'())))
+		      '())))
 
 	   (cond
 	    ;; Long option.
@@ -216,41 +216,42 @@
 		 (begin
 		   (for-each no-option (cdr ptr))
 		   (set! ptr (cons #f '())))
-		 ;; Normal case.
-		 (let* ((name (string-drop arg 2))
-			(index (string-index name #\=))
-			(param #f)
-			(target-option #f))
-		   (and index
-			(begin
-			  ;; It is of the form `--option=parameter'.
-			  (set! param (string-drop name (1+ index)))
-			  (set! name (string-take name index))))
-		   ;; Find the right one.
-		   (set! target-option (find-long-option name))
-		   (and (boolean? target-option)
-			(begin
-			  (local-output
-			   (if target-option
-			       (l10n "Option `--~a' is ambigous.")
-			       (l10n "Unknown option: `--~a'."))
-			   name)
-			  (local-output "Try `--help'.")
-			  (quit 1)))
-		   (and (takes-arg? target-option)
-			(not (optional-arg? target-option))
-			(not param)
-			(not (null? (cdr ptr)))
-			(not (string-prefix? "-" (cadr ptr)))
-			(begin
-			  ;; If we reach this point, it means that we
-			  ;; need a parameter, we have none, there is
-			  ;; another argument and it does not look like
-			  ;; an option.  In this case, we obviously use
-			  ;; that as parameter.
-			  (set! ptr (cdr ptr))
-			  (set! param (car ptr))))
-		   (apply-option target-option param))))
+	       ;; Normal case.
+	       (let* ((name (string-drop arg 2))
+		      (index (string-index name #\=))
+		      (param #f)
+		      (target-option #f))
+		 (and index
+		      (begin
+			;; It is of the form `--option=parameter'.
+			(set! param (string-drop name (1+ index)))
+			(set! name (string-take name index))))
+		 ;; Find the right one (as it might be abbreviated).
+		 (set! target-option (find-long-option name))
+		 (and (boolean? target-option)
+		      (begin
+			(local-output
+			 (if target-option
+			     (l10n "Option `--~a' is ambigous.")
+			   (l10n "Unknown option: `--~a'."))
+			 name)
+			(local-output "Try `--help'.")
+			(quit 1)))
+		 (and (takes-arg? target-option)
+		      (not (optional-arg? target-option))
+		      (not param)
+		      (not (null? (cdr ptr)))
+		      (or (not (string-prefix? "-" (cadr ptr)))
+			  (string=? "-" (cadr ptr)))
+		      (begin
+			;; If we reach this point, it means that we
+			;; need a parameter, we have none, there is
+			;; another argument and it does not look like
+			;; an option.  In this case, we obviously use
+			;; that as parameter.
+			(set! ptr (cdr ptr))
+			(set! param (car ptr))))
+		 (apply-option target-option param))))
 	    ;; Short option.
 	    ((string-prefix? "-" arg)
 	     (let* ((opt-char (string-ref arg 1))
@@ -260,29 +261,30 @@
 		   (begin
 		     (local-output "Unknown option: `-~a'." opt-char)
 		     (quit 1))
-		   (if (takes-arg? target-option)
-		       (begin
-			 (if (= (string-length arg) 2)
-			     ;; Take next argument as param.
-			     (if (or (null? (cdr ptr))
-				     (string-prefix? "-" (cadr ptr)))
-				 (or (optional-arg? target-option)
-				     (begin
-				       (local-output
-					"Argument required by `-~a'." opt-char)
-				       (quit 1)))
-				 (begin
-				   (set! ptr (cdr ptr))
-				   (set! param (car ptr))))
-			     ;; Parameter is the rest of this argument.
-			     (set! param (string-drop arg 2)))
-			 (apply-option target-option param))
-		       ;; Does not take a parameter, thus the
-		       ;; following chars are also options without
-		       ;; parameter.
-		       (for-each (lambda (c)
-				   (apply-option (find-short-option c) #f))
-				 (string->list (string-drop arg 1)))))))
+		 (if (takes-arg? target-option)
+		     (begin
+		       (if (= (string-length arg) 2)
+			   ;; Take next argument as param.
+			   (if (or (null? (cdr ptr))
+				   (and (string-prefix? "-" (cadr ptr))
+					(not (string=? "-" (cadr ptr)))))
+			       (or (optional-arg? target-option)
+				   (begin
+				     (local-output
+				      "Argument required by `-~a'." opt-char)
+				     (quit 1)))
+			     (begin
+			       (set! ptr (cdr ptr))
+			       (set! param (car ptr))))
+			 ;; Parameter is the rest of this argument.
+			 (set! param (string-drop arg 2)))
+		       (apply-option target-option param))
+		   ;; Does not take a parameter, thus the
+		   ;; following chars are also options without
+		   ;; parameter.
+		   (for-each (lambda (c)
+			       (apply-option (find-short-option c) #f))
+			     (string->list (string-drop arg 1)))))))
 	    ;; Not interpreted as option.
 	    (else
 	     (no-option arg)))
diff -urN dmd--0.7/comm.scm dmd--0.5/comm.scm
--- dmd--0.7/comm.scm	2002-12-28 12:23:59.000000000 +0100
+++ dmd--0.5/comm.scm	2003-03-25 18:10:59.000000000 +0100
@@ -1,5 +1,5 @@
-;; comm.scm -- Communication between processes.
-;; Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+;; comm.scm -- Communication between processes and general output.
+;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;;
 ;; This is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -16,9 +16,8 @@
 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA  02111-1307, USA.
 
-;; This encapsulates the exact semantics of the communication between
-;; deco and dmd.  It provides convenient classes for sending and
-;; receiving data.
+;; This file encapsulates the exact semantics of the communication
+;; between deco and dmd.  It also does the other output stuff.
 
 (define-class <sender> ()
   target-file
@@ -50,7 +49,7 @@
   (assert (= (length args) 1))
   (slot-set! obj 'socket (socket PF_UNIX SOCK_DGRAM 0))
   ;; Make the socket available to us.
-  (without-system-error (delete-file (car args)))
+  (catch-system-error (delete-file (car args)))
   (bind (slot-ref obj 'socket) AF_UNIX (car args)))
 
 ;; Get a message from the receiver.
@@ -65,14 +64,14 @@
     (define (select+recv)
       (let retry ()
 	(catch 'system-error
-	       (lambda ()
-		 (select (list sock) '() '())
-		 (recv! sock buf))
-	       (lambda (key . args)
-		 ;; Usually this will be an interruption of select due
-		 ;; to a signal, but in any case we cannot do much
-		 ;; else, except for aborting.
-		 (retry)))))
+	  (lambda ()
+	    (select (list sock) '() '())
+	    (recv! sock buf))
+	  (lambda (key . args)
+	    ;; Usually this will be an interruption of select due to a
+	    ;; signal, but in any case we cannot do much else (except
+	    ;; for aborting maybe).
+	    (retry)))))
 
     ;; Get length of message, then the message itself.
     (set! len (string->number (string-take buf (select+recv))))
@@ -83,3 +82,109 @@
     (or (= real-len len)
 	(local-output "Invalid data received."))
     buf))
+
+
+
+;; FIXME: That may be ``good enough'', but should be fixed anyway.
+;; For communication between deco and dmd.
+(define terminating-string "!§&§&§&§&!") ;; Unlikely to appear in output.
+
+(begin-dmd
+ ;; Create a `backup' of the original standard output.
+ (define original-output-port (current-output-port))
+
+ ;; Port for logging.  This must always be a valid port, never `#f'.
+ (define log-output-port (%make-void-port "w"))
+ (define (start-logging file)
+   (set! log-output-port (open-file file "wl"))) ;; Line-buffered port.
+ (define (stop-logging)
+   (set! log-output-port (%make-void-port "w")))
+
+ ;; Whether we should be silent.
+ (define silent #f)
+ (define (be-silent) (set! silent #t))
+ (define (be-verbose) (set! silent #f))
+
+ ;; Additional output destination, if any.
+ (define extra-output-sender #f)
+ (define (open-extra-sender file)
+   (catch 'system-error
+     (lambda ()
+       (set! extra-output-sender (make <sender> file)))
+     (lambda (key . args)
+       (local-output "Failed to open ~a." file))))
+ (define (close-extra-sender)
+   (catch-system-error
+    (send-data extra-output-sender terminating-string)
+    (set! extra-output-sender #f)))
+
+ (define-syntax-rule (without-extra-output EXPR ...)
+   (let ((sender extra-output-sender))
+     (dynamic-wind
+	 (lambda ()
+	   (set! extra-output-sender #f))
+	 (lambda ()
+	   EXPR ...)
+	 (lambda ()
+	   (set! extra-output-sender sender)))))
+
+ ;; We provide our own output mechanism, because we have certain
+ ;; special needs; most importantly, we want to send output to deco
+ ;; sometimes.
+ (define dmd-output-port
+   (make-soft-port
+    (vector
+
+     ;; One character for output.
+     (lambda (char)
+       (display (string char)))
+
+     ;; A string for output.
+     (let ((buffer '())) ;; List of unwritten output strings.
+       (lambda (str)
+	 ;; Standard output, display directly.
+	 (display str original-output-port)
+	 ;; Socket to deco, send directly.
+	 (and extra-output-sender
+	      (catch-system-error
+	       (send-data extra-output-sender str)))
+	 ;; Logfile, buffer line-wise and output time for each
+	 ;; completed line.
+	 (if (not (string-index str #\newline))
+	     (set! buffer (cons str buffer))
+	   (let* ((log (lambda (x)
+			 (display x log-output-port)))
+		  (init-line (lambda ()
+			       (log (strftime "%Y-%m-%d %H:%M:%S "
+					      (localtime (current-time)))))))
+	     (init-line)
+	     (for-each log (reverse buffer))
+	     (let* ((lines (string-split str #\newline))
+		    (last-line (car (take-right lines 1)))
+		    (is-first #t))
+	       (for-each (lambda (line)
+			   (if is-first
+			       (set! is-first #f)
+			     (init-line))
+			   (log line)
+			   (log #\newline))
+			 (drop-right lines 1))
+	       (set! buffer (if (string-null? last-line)
+				'()
+			      (list last-line))))))))
+
+     ;; Flush output.
+     (lambda ()
+      ;; FIXME: Do we need to do something?  Flush the logfile buffer?
+       #t)
+
+     ;; Get a character (unused).
+     #f
+
+     ;; Close the port.
+     (lambda () #t))
+
+    ;; It's an output-only port.
+    "w"))
+
+ (set-current-output-port dmd-output-port))
diff -urN dmd--0.7/config.scm.in dmd--0.5/config.scm.in
--- dmd--0.7/config.scm.in	2003-01-01 01:04:00.000000000 +0100
+++ dmd--0.5/config.scm.in	2003-02-25 17:31:58.000000000 +0100
@@ -3,6 +3,5 @@
 (define Version "%VERSION%")
 (define Prefix-dir "%PREFIX%")
 
-(define banner (string-append program-name " " Version))
 (define copyright "Copyright (C) 2002, 2003 Wolfgang Jährling")
 (define bug-address "wolfgang@pro-linux.de")
\ No newline at end of file
diff -urN dmd--0.7/configure dmd--0.5/configure
--- dmd--0.7/configure	2002-10-12 15:41:06.000000000 +0200
+++ dmd--0.5/configure	2003-04-08 17:09:02.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.54.
+# Generated by GNU Autoconf 2.57.
 #
 # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
@@ -36,7 +36,10 @@
 PS4='+ '
 
 # NLS nuisances.
-for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
 do
   if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
@@ -82,15 +85,15 @@
 
 # The user is always right.
 if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conftest.sh
-  echo  "exit 0"   >>conftest.sh
-  chmod +x conftest.sh
-  if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
     PATH_SEPARATOR=';'
   else
     PATH_SEPARATOR=:
   fi
-  rm -f conftest.sh
+  rm -f conf$$.sh
 fi
 
 
@@ -268,7 +271,7 @@
 PACKAGE_BUGREPORT=
 
 ac_unique_file="dmd.scm"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE GUILE GUILE_CONFIG GUILE_TOOLS LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -857,7 +860,7 @@
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.54.  Invocation command line was
+generated by GNU Autoconf 2.57.  Invocation command line was
 
   $ $0 $@
 
@@ -909,24 +912,54 @@
 
 # Keep a trace of the command line.
 # Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
 # Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
 ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
 ac_sep=
-for ac_arg
+ac_must_keep_next=false
+for ac_pass in 1 2
 do
-  case $ac_arg in
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c | -n ) continue ;;
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    continue ;;
-  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-    ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-  esac
-  ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
-  # Get rid of the leading space.
-  ac_sep=" "
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+        ac_must_keep_next=false # Got value, back to normal.
+      else
+        case $ac_arg in
+          *=* | --config-cache | -C | -disable-* | --disable-* \
+          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+          | -with-* | --with-* | -without-* | --without-* | --x)
+            case "$ac_configure_args0 " in
+              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+            esac
+            ;;
+          -* ) ac_must_keep_next=true ;;
+        esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
 done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
 
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
@@ -1369,15 +1402,15 @@
   test -n "$AWK" && break
 done
 
-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
 if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.make <<\_ACEOF
 all:
-	@echo 'ac_maketemp="${MAKE}"'
+	@echo 'ac_maketemp="$(MAKE)"'
 _ACEOF
 # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
 eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
@@ -1408,7 +1441,7 @@
 
 # Define the identity of the package.
  PACKAGE=dmd
- VERSION=-0.7
+ VERSION=-0.5
 
 
 cat >>confdefs.h <<_ACEOF
@@ -1535,6 +1568,159 @@
 
 
 
+# Extract the first word of "guile", so it can be a program name with args.
+set dummy guile; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GUILE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GUILE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GUILE="$GUILE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GUILE="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GUILE=$ac_cv_path_GUILE
+
+if test -n "$GUILE"; then
+  echo "$as_me:$LINENO: result: $GUILE" >&5
+echo "${ECHO_T}$GUILE" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  if test "$GUILE" = "" ; then
+      { { echo "$as_me:$LINENO: error: guile required but not found" >&5
+echo "$as_me: error: guile required but not found" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+
+  # Extract the first word of "guile-config", so it can be a program name with args.
+set dummy guile-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GUILE_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GUILE_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GUILE_CONFIG="$GUILE_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GUILE_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GUILE_CONFIG=$ac_cv_path_GUILE_CONFIG
+
+if test -n "$GUILE_CONFIG"; then
+  echo "$as_me:$LINENO: result: $GUILE_CONFIG" >&5
+echo "${ECHO_T}$GUILE_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  if test "$GUILE_CONFIG" = "" ; then
+      { { echo "$as_me:$LINENO: error: guile-config required but not found" >&5
+echo "$as_me: error: guile-config required but not found" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+
+  # Extract the first word of "guile-tools", so it can be a program name with args.
+set dummy guile-tools; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GUILE_TOOLS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GUILE_TOOLS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GUILE_TOOLS="$GUILE_TOOLS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GUILE_TOOLS="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GUILE_TOOLS=$ac_cv_path_GUILE_TOOLS
+
+if test -n "$GUILE_TOOLS"; then
+  echo "$as_me:$LINENO: result: $GUILE_TOOLS" >&5
+echo "${ECHO_T}$GUILE_TOOLS" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+
+echo "$as_me:$LINENO: checking whether it is at least guile 1.5.x" >&5
+echo $ECHO_N "checking whether it is at least guile 1.5.x... $ECHO_C" >&6
+
+  $GUILE -c "(or (>= (string->number (major-version)) 2)
+    (and (>= (string->number (major-version)) 1)
+         (>= (string->number (minor-version)) 5))
+    (quit 1))
+" > /dev/null 2>&1
+  version_ok=$?
+
+if test $version_ok = 0; then
+  recent_version=yes
+else
+  recent_version=no
+fi
+echo "$as_me:$LINENO: result: $recent_version" >&5
+echo "${ECHO_T}$recent_version" >&6
+if test $recent_version = no; then
+  { echo "$as_me:$LINENO: WARNING: your guile is probably too old to run dmd" >&5
+echo "$as_me: WARNING: your guile is probably too old to run dmd" >&2;}
+fi
 
 
 
@@ -1585,7 +1771,7 @@
      t end
      /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
      : end' >>confcache
-if cmp -s $cache_file confcache; then :; else
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
   if test -w $cache_file; then
     test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
     cat confcache >$cache_file
@@ -1676,6 +1862,8 @@
 # configure, is in config.log if it exists.
 
 debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
 SHELL=\${CONFIG_SHELL-$SHELL}
 _ACEOF
 
@@ -1710,7 +1898,10 @@
 PS4='+ '
 
 # NLS nuisances.
-for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
 do
   if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
@@ -1756,15 +1947,15 @@
 
 # The user is always right.
 if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conftest.sh
-  echo  "exit 0"   >>conftest.sh
-  chmod +x conftest.sh
-  if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
     PATH_SEPARATOR=';'
   else
     PATH_SEPARATOR=:
   fi
-  rm -f conftest.sh
+  rm -f conf$$.sh
 fi
 
 
@@ -1927,7 +2118,7 @@
 cat >&5 <<_CSEOF
 
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.54.  Invocation command line was
+generated by GNU Autoconf 2.57.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -1967,6 +2158,7 @@
 
   -h, --help       print this help, then exit
   -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
   --file=FILE[:TEMPLATE]
@@ -1981,7 +2173,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.54,
+configured by $0, generated by GNU Autoconf 2.57,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
@@ -2018,12 +2210,9 @@
   case $ac_option in
   # Handling of the options.
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
-    exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
-_ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
   --version | --vers* | -V )
     echo "$ac_cs_version"; exit 0 ;;
   --he | --h)
@@ -2045,6 +2234,9 @@
     $ac_shift
     CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
     ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
 
   # This is an error.
   -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
@@ -2059,6 +2251,20 @@
   shift
 done
 
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
 _ACEOF
 
 
@@ -2087,6 +2293,9 @@
   test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
 fi
 
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
 # Create a temporary directory, and hook for its removal unless debugging.
 $debug ||
 {
@@ -2095,17 +2304,17 @@
 }
 
 # Create a (secure) tmp directory for tmp files.
-: ${TMPDIR=/tmp}
+
 {
-  tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
   test -n "$tmp" && test -d "$tmp"
 }  ||
 {
-  tmp=$TMPDIR/cs$$-$RANDOM
+  tmp=./confstat$$-$RANDOM
   (umask 077 && mkdir $tmp)
 } ||
 {
-   echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+   echo "$me: cannot create a temporary directory in ." >&2
    { (exit 1); exit 1; }
 }
 
@@ -2170,6 +2379,9 @@
 s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
 s,@AWK@,$AWK,;t t
 s,@SET_MAKE@,$SET_MAKE,;t t
+s,@GUILE@,$GUILE,;t t
+s,@GUILE_CONFIG@,$GUILE_CONFIG,;t t
+s,@GUILE_TOOLS@,$GUILE_TOOLS,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF
@@ -2396,8 +2608,11 @@
 # need to make the FD available again.
 if test "$no_create" != yes; then
   ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
   exec 5>/dev/null
-  $SHELL $CONFIG_STATUS || ac_cs_success=false
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
diff -urN dmd--0.7/configure.in dmd--0.5/configure.in
--- dmd--0.7/configure.in	2002-10-12 15:40:11.000000000 +0200
+++ dmd--0.5/configure.in	2003-04-08 17:08:29.000000000 +0200
@@ -2,10 +2,27 @@
 
 dnl Initialization
 AC_INIT(dmd.scm)
-AM_INIT_AUTOMAKE(dmd,-0.7)
+AM_INIT_AUTOMAKE(dmd,-0.5)
 
 dnl Checks for programs.
-dnl FIXME: Check for Guile.
+GUILE_PROGS
+
+AC_MSG_CHECKING(whether it is at least guile 1.5.x)
+GUILE_CHECK(version_ok,
+(or (>= (string->number (major-version)) 2)
+    (and (>= (string->number (major-version)) 1)
+         (>= (string->number (minor-version)) 5))
+    (quit 1))
+)
+if test $version_ok = 0; then
+  recent_version=yes
+else
+  recent_version=no
+fi
+AC_MSG_RESULT($recent_version)
+if test $recent_version = no; then
+  AC_MSG_WARN(your guile is probably too old to run dmd)
+fi
 
 dnl Checks for libraries.
 
diff -urN dmd--0.7/deco.scm dmd--0.5/deco.scm
--- dmd--0.7/deco.scm	2002-12-28 12:23:59.000000000 +0100
+++ dmd--0.5/deco.scm	2003-03-12 21:19:23.000000000 +0100
@@ -1,5 +1,5 @@
 ;; deco.scm -- The `DaEmon COntrol' program.
-;; Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;;
 ;; This is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -19,7 +19,6 @@
 (define program-name "deco")
 
 (use-modules (ice-9 syncase)  ;; R5RS macros.
-	     (ice-9 rdelim)   ;; Line-based I/O.
 	     (oop goops)      ;; OO support.
 	     (srfi srfi-1)    ;; List library.
 	     (srfi srfi-13))  ;; String library.
@@ -83,10 +82,9 @@
       (letrec ((next-line (lambda (line)
 			    (if (string=? line terminating-string)
 				(quit)
-				(begin
-				  (display line)
-				  (newline)
-				  (next-line (receive-data receiver)))))))
+			      (begin
+				(display line)
+				(next-line (receive-data receiver)))))))
 	(next-line (receive-data receiver))))))
 
 (main (cdr (command-line)))
diff -urN dmd--0.7/dmd.info dmd--0.5/dmd.info
--- dmd--0.7/dmd.info	2003-02-20 17:13:28.000000000 +0100
+++ dmd--0.5/dmd.info	2003-05-01 22:40:33.000000000 +0200
@@ -1,4 +1,4 @@
-Dies ist dmd.info, hergestellt von Makeinfo Version 4.0 aus dmd.texi.
+This is dmd.info, produced by makeinfo version 4.0 from dmd.texi.
 
 INFO-DIR-SECTION System software
 START-INFO-DIR-ENTRY
@@ -11,7 +11,7 @@
 dmd Manual
 **********
 
-   Copyright (C) 2002 Wolfgang Ja"hrling
+   Copyright (C) 2002, 2003 Wolfgang Ja"hrling
 
    Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
@@ -225,8 +225,8 @@
    The daemon that runs in the background and is responsible for
 controlling the services is "dmd", while the user interface tool is
 called "deco", the "DaEmon COntroller"(1).  To perform an action, like
-stopping a service or calling an extra-action of a service, you use the
-deco program.  It will communicate with dmd over a Unix Domain Socket.
+stopping a service or calling an action of a service, you use the deco
+program.  It will communicate with dmd over a Unix Domain Socket.
 
    Thus, you start dmd once, and then always use deco whenever you want
 to do something service-related.  Since deco passes its current working
@@ -411,10 +411,10 @@
      later point.  The default value is a procedure that returns `#f'
      and performs no further actions.
 
-   * `extra-actions' specifies the additional actions that can be
-     performed on a service when it is running.  A typical example for
-     this is the `restart' action.  The macro `make-extra-actions'
-     *Note Service Convenience:: is provided to abstract the actual data
+   * `actions' specifies the additional actions that can be performed
+     on a service when it is running.  A typical example for this is the
+     `restart' action.  The macro `make-actions' *Note Service
+     Convenience:: is provided to abstract the actual data
      representation format for this slot.  (It actually is a hash
      currently.)
 
@@ -471,10 +471,10 @@
      `start' method.  The return value is also the new `running' value,
      thus `#f' if the service was stopped.
 
- - method: extra-action (obj <service>) action . args
-     Calls the extra-action ACTION (a symbol) of the service OBJ, with
-     the specified ARGS, which are dependend on the particular
-     extra-action.
+ - method: action (obj <service>) the-action . args
+     Calls the action THE-ACTION (a symbol) of the service OBJ, with
+     the specified ARGS, which have a meaning depending on the
+     particular action.
 
  - method: conflicts-with (obj <service>)
      Returns a list of the canonical names of services that conflict
@@ -499,8 +499,8 @@
 
  - method: default-display-status (obj <service>)
      Display status information about OBJ.  This method is called when
-     the user performs the extra-action `status' on OBJ, but there is
-     no specific implementation given for it.  It is also called when
+     the user performs the action `status' on OBJ, but there is no
+     specific implementation given for it.  It is also called when
      `detailed-status' is applied on `dmd'.
 
 
@@ -521,12 +521,12 @@
      Return a list of all registered services which provide the symbol
      NAME.
 
- - macro: make-extra-actions (name proc) ...
-     This macro is used to create a value for the `extra-actions' slot
-     of a service object *Note Slots of services::.  Each NAME is a
-     symbol and each PROC the corresponding procedure that will be
-     called to perform the action.  A PROC has one argument, which will
-     be the current value of the `running' slot of the service.
+ - macro: make-actions (name proc) ...
+     This macro is used to create a value for the `actions' slot of a
+     service object *Note Slots of services::.  Each NAME is a symbol
+     and each PROC the corresponding procedure that will be called to
+     perform the action.  A PROC has one argument, which will be the
+     current value of the `running' slot of the service.
 
  - method: start (obj <symbol>)
      Start a registered service providing OBJ.
@@ -534,9 +534,9 @@
  - method: stop (obj <symbol>)
      Stop a registered service providing OBJ.
 
- - method: extra-action (obj <symbol>) action . args
-     The same as the `extra-action' method of class `<service>', but
-     uses a service that provides OBJ and is running.
+ - method: action (obj <symbol>) the-action . args
+     The same as the `action' method of class `<service>', but uses a
+     service that provides OBJ and is running.
 
  - procedure: for-each-service proc
      Call PROC, a procedure taking one argument, once for each
@@ -609,9 +609,9 @@
              #:requires '()
              #:start (...)
              #:stop (...)
-             #:extra-actions (make-extra-actions
-                               (reload-modules (...))
-                               (restart (...)))))
+             #:actions (make-actions
+                        (reload-modules (...))
+                        (restart (...)))))
 
 
 File: dmd.info,  Node: The dmd and unknown services,  Prev: Service Examples,  Up: Services
@@ -620,8 +620,8 @@
 ================================
 
    The service `dmd' is special, because it is used to control dmd
-itself.  It provides the following extra-actions (in addition to
-`enable', `disable' and `restart' which do not make sense here).
+itself.  It provides the following actions (in addition to `enable',
+`disable' and `restart' which do not make sense here).
 
 ``status''
      Displays which services are started and which ones are not.
@@ -780,12 +780,30 @@
 
 * Menu:
 
+* Coding standards::    How to properly hack dmd.
 * Design decisions::    Why dmd is what it is.
 * Service Internals::   How services actually work.
 * Runlevel evolution::  Learning from past mistakes.
 
 
-File: dmd.info,  Node: Design decisions,  Next: Service Internals,  Up: Internals
+File: dmd.info,  Node: Coding standards,  Next: Design decisions,  Up: Internals
+
+Coding standards
+================
+
+   About formatting: Use common sense and GNU Emacs (which actually is
+the same, of course), and you almost can't get the formatting wrong.
+Notable exceptions: Indent `if' like it is done in ELisp, and `catch'
+also deserves a better indenting.  This can be achieved by putting this
+in your `~/.emacs':
+
+     (put 'if 'scheme-indent-function 2)
+     (put 'catch 'scheme-indent-function 1)
+
+   This section will be extended in the future...
+
+
+File: dmd.info,  Node: Design decisions,  Next: Service Internals,  Prev: Coding standards,  Up: Internals
 
 Design decisions
 ================
@@ -891,12 +909,11 @@
      recalculating what needs to be done whenever starting a service
      fails, also marking that particular service as unstartable, except
      if it fails to start because a dependency could not be resolved
-     (or maybe even then?).  This is even more complicated (and somehow
-     smells for `call/cc', don't you think?).  Instead of implementing
-     this and thereby producing code that (a) nobody understands, (b)
-     certainly has a lot of bugs, (c) will be unmaintainable and (d)
-     causes users to panic because they won't understand what will
-     happen, I decided to do the following instead:
+     (or maybe even then?).  This is even more complicated.  Instead of
+     implementing this and thereby producing code that (a) nobody
+     understands, (b) certainly has a lot of bugs, (c) will be
+     unmaintainable and (d) causes users to panic because they won't
+     understand what will happen, I decided to do the following instead:
 
    * Just report the error, and let the user fix it (in this case, fix
      the configuration of A) or work around it (in this case, disable A
@@ -938,8 +955,7 @@
 
 * Runlevel assumptions::    What runlevels should be like
 * Runlevels - part one::    The first attempts of making it work
-* Runlevels - part two::    A more promising attempt
-* Runlevels - part three::  It should work... somehow...
+* Runlevels - part two::    It should work... somehow...
 
 
 File: dmd.info,  Node: Runlevel assumptions,  Next: Runlevels - part one,  Up: Runlevel evolution
@@ -986,14 +1002,8 @@
 Runlevels, part one
 -------------------
 
-
-File: dmd.info,  Node: Runlevels - part two,  Next: Runlevels - part three,  Prev: Runlevels - part one,  Up: Runlevel evolution
-
-Runlevels, part two
--------------------
-
-   I came up with the following algorithm (here in Pseudo-Scheme), which
-is possibly slightly buggy, but should give you the idea:
+   I came up with the following method (here in Pseudo-Scheme), which is
+possibly slightly buggy, but should give you the idea:
 
      ;; Beginning with the canonical names in CURRENT-SERVICES, start and
      ;; stop services until getting into a state where everything requested
@@ -1072,10 +1082,10 @@
    Thus, we cannot do it this way.
 
 
-File: dmd.info,  Node: Runlevels - part three,  Prev: Runlevels - part two,  Up: Runlevel evolution
+File: dmd.info,  Node: Runlevels - part two,  Prev: Runlevels - part one,  Up: Runlevel evolution
 
-Runlevels, part three
----------------------
+Runlevels, part two
+-------------------
 
    Let's look again at the table at the end of part two:
 
@@ -1119,7 +1129,7 @@
 must be used (and somehow we should take into account which services
 are running already).  This also reduces the amount of possible
 combinations a lot.  So what remains after that are the services we
-might need for fulfilling dependencies.  For them, we could to try all
+might need for fulfilling dependencies.  For them, we could try all
 combinations (2^n), making sure that we always try subsets before any
 of their supersets to avoid starting unneeded services.  We should take
 into account which services are already running as well.
@@ -1142,7 +1152,7 @@
 * Menu:
 
 * <service>, slots of:                   Slots of services.
-* Addition actions of services:          Slots of services.
+* Actions of services:                   Slots of services.
 * assertions:                            Errors.
 * canonical names of services:           Slots of services.
 * configuration file:                    Jump Start.
@@ -1155,7 +1165,6 @@
 * dmd:                                   deco and dmd.
 * dmd Invocation:                        Invoking dmd.
 * dmd service:                           The dmd and unknown services.
-* Extra actions of services:             Slots of services.
 * fallback service:                      The dmd and unknown services.
 * fallback services:                     Jump Start.
 * generating constructors:               Service De- and Constructors.
@@ -1177,6 +1186,7 @@
 * Scheme:                                Introduction.
 * security:                              Invoking dmd.
 * service:                               Services.
+* Service actions:                       Slots of services.
 * Service constructor:                   Slots of services.
 * Service destructor:                    Slots of services.
 * service manager:                       Introduction.
@@ -1198,6 +1208,8 @@
 
 * Menu:
 
+* action <1>:                            Service Convenience.
+* action:                                Methods of services.
 * assert:                                Errors.
 * call/cc:                               Errors.
 * call/ec:                               Errors.
@@ -1207,14 +1219,12 @@
 * copy-hashq-table:                      Others.
 * default-display-status:                Methods of services.
 * enter:                                 Runlevels.
-* extra-action <1>:                      Service Convenience.
-* extra-action:                          Methods of services.
 * find-running:                          Service Convenience.
 * for-each-service:                      Service Convenience.
 * local-output:                          Communication.
 * lookup-services:                       Service Convenience.
+* make-actions:                          Service Convenience.
 * make-childexec-constructor:            Service De- and Constructors.
-* make-extra-actions:                    Service Convenience.
 * make-kill-destructor:                  Service De- and Constructors.
 * make-system-constructor:               Service De- and Constructors.
 * make-system-destructor:                Service De- and Constructors.
@@ -1239,8 +1249,8 @@
 
 * Menu:
 
+* actions (slot of <service>):           Slots of services.
 * enabled? (slot of <service>):          Slots of services.
-* extra-actions (slot of <service>):     Slots of services.
 * last-respawns (slot of <service>):     Slots of services.
 * provides (slot of <service>):          Slots of services.
 * requires (slot of <service>):          Slots of services.
@@ -1267,36 +1277,36 @@
 
 
 Tag Table:
-Node: Top208
-Node: Introduction1167
-Node: Jump Start2678
-Node: deco and dmd9817
-Ref: deco and dmd-Footnote-110718
-Node: Invoking dmd10829
-Node: Invoking deco12101
-Node: Services13360
-Node: Slots of services14232
-Node: Methods of services19223
-Node: Service Convenience21591
-Node: Service De- and Constructors23364
-Node: Service Examples24985
-Node: The dmd and unknown services25975
-Node: Runlevels27340
-Node: Misc Facilities27886
-Node: Errors28382
-Node: Communication29426
-Node: Others30760
-Node: Internals31139
-Node: Design decisions31838
-Node: Service Internals39627
-Node: Runlevel evolution39776
-Node: Runlevel assumptions40410
-Node: Runlevels - part one42319
-Node: Runlevels - part two42490
-Node: Runlevels - part three46102
-Node: Concept Index49261
-Node: Procedure and Macro Index52196
-Node: Variable Index54280
-Node: Type Index55092
+Node: Top204
+Node: Introduction1169
+Node: Jump Start2680
+Node: deco and dmd9819
+Ref: deco and dmd-Footnote-110714
+Node: Invoking dmd10825
+Node: Invoking deco12097
+Node: Services13356
+Node: Slots of services14228
+Node: Methods of services19207
+Node: Service Convenience21570
+Node: Service De- and Constructors23323
+Node: Service Examples24944
+Node: The dmd and unknown services25908
+Node: Runlevels27267
+Node: Misc Facilities27813
+Node: Errors28309
+Node: Communication29353
+Node: Others30687
+Node: Internals31066
+Node: Coding standards31815
+Node: Design decisions32374
+Node: Service Internals40130
+Node: Runlevel evolution40279
+Node: Runlevel assumptions40860
+Node: Runlevels - part one42769
+Node: Runlevels - part two46376
+Node: Concept Index49526
+Node: Procedure and Macro Index52461
+Node: Variable Index54545
+Node: Type Index55357
 
 End Tag Table
diff -urN dmd--0.7/dmd.scm dmd--0.5/dmd.scm
--- dmd--0.7/dmd.scm	2003-02-17 17:57:34.000000000 +0100
+++ dmd--0.5/dmd.scm	2003-04-25 16:58:51.000000000 +0200
@@ -20,9 +20,11 @@
 
 (use-modules (ice-9 syncase)  ;; R5RS macros.
 	     (ice-9 rdelim)   ;; Line-based I/O.
-	     (oop goops)      ;; OO support.
+	     (ice-9 readline) ;; Readline (for interactive use).
+	     (oop goops)      ;; Defining classes and methods.
 	     (srfi srfi-1)    ;; List library.
-	     (srfi srfi-13))  ;; String library.
+	     (srfi srfi-13)   ;; String library.
+	     (srfi srfi-16))  ;; `case-lambda'.
 
 (debug-enable 'backtrace)
 
@@ -95,12 +97,24 @@
 		  (make <option>
 		    #:long "socket" #:short #\s
 		    #:takes-arg? #t #:optional-arg? #f #:arg-name "FILE"
-		    #:description "get commands from socket FILE or from stdin"
+		    #:description
+		    "get commands from socket FILE or from stdin (-)"
 		    #:action (lambda (file)
 			       (set! socket-file
-				     (if (string=? file "none")
-					 #f
-					 file)))))
+				     (if (not (string=? file "-"))
+					 file
+				       ;; We will read commands
+				       ;; from stdin, thus we
+				       ;; enable readline if it is
+				       ;; a non-dumb terminal.
+				       (and (isatty? (current-input-port))
+					    (not (string=? (getenv "TERM")
+							   "dumb"))
+					    (begin
+					      (activate-readline)
+					      ;; Finally, indicate that
+					      ;; we use no socket.
+					      #f)))))))
     ;; We do this early so that we can abort early if necessary.
     (and socket-file
 	 (verify-dir (dirname socket-file) insecure))
@@ -112,85 +126,102 @@
     ;; Start the dmd service.
     (start dmd-service)
     ;; This _must_ succeed.  (We could also put the `catch' around
-    ;; `main', but it is often useful to get the backtrace.)
+    ;; `main', but it is often useful to get the backtrace, and
+    ;; `caught-error' does not do this yet.)
     (catch #t
-	   (lambda ()
-	     (load config-file))
-	   (lambda (key . args)
-	     (caught-error key args)
-	     (quit 1)))
+      (lambda ()
+	(load config-file))
+      (lambda (key . args)
+	(caught-error key args)
+	(quit 1)))
     ;; Start what was started last time.
     (and persistency
 	 (catch 'system-error
-		(lambda ()
-		  (start-in-order (read (open-input-file
-					 persistency-state-file))))
-		(lambda (key . args)
-		  (apply local-output (cadr args) (caddr args))
-		  (quit 1))))
+	   (lambda ()
+	     (start-in-order (read (open-input-file
+				    persistency-state-file))))
+	   (lambda (key . args)
+	     (apply local-output (cadr args) (caddr args))
+	     (quit 1))))
 
     (if (not socket-file)
 	;; Get commands from the standard input port.
-	(while #t (process-command
-		   (apply list
-			  "." #f ;; Use current dir, no socket output.
-			  (string-tokenize (read-line)))))
-	;; Process the data arriving at a socket.
-	(let ((command-source (make <receiver> socket-file))
-	      (greeting #f))
-	  (letrec
-	      ((next-command
-		(lambda ()
-		  ;; Get number of messages first.
-		  (set! greeting (receive-data command-source))
-		  (letrec
-		      ((next-message
-			(lambda (messages-left msg-list)
-			  (and (not messages-left)
-			       (begin ;; Not a valid number.
-				 (local-output "Invalid data received.")
-				 (set! messages-left 0)))
-			  (if (zero? messages-left)
-			      (process-command (reverse! msg-list))
-			      (next-message (- messages-left 1)
-					    (cons (receive-data command-source)
-						  msg-list))))))
-		    (next-message (string->number greeting)
-				  '()))
-		  (next-command))))
-	    (next-command))))))
+	(begin
+	  (call/ec (lambda (done)
+		     (while #t (process-command
+				(apply list
+				       ;; Use current dir, no socket output.
+				       "." #f
+				       (string-tokenize
+					(let ((line (read-line)))
+					  (if (eof-object? line)
+					      (done #t)
+					    line))))))))
+	  ;; Exit on `C-d'.
+	  (stop dmd-service))
+      ;; Process the data arriving at a socket.
+      (let ((command-source (make <receiver> socket-file))
+	    (greeting #f))
+	(letrec
+	    ((next-command
+	      (lambda ()
+		;; Get number of messages first.
+		(set! greeting (receive-data command-source))
+		(letrec
+		    ((next-message
+		      (lambda (messages-left msg-list)
+			(and (not messages-left)
+			     (begin ;; Not a valid number.
+			       (local-output "Invalid data received.")
+			       (set! messages-left 0)))
+			(if (zero? messages-left)
+			    (process-command (reverse! msg-list))
+			  (next-message (- messages-left 1)
+					(cons (receive-data command-source)
+					      msg-list))))))
+		  (next-message (string->number greeting)
+				'()))
+		(next-command))))
+	  (next-command))))))
 
 ;; Interpret COMMAND, a command sent by the user, represented as a
 ;; list of strings.
 (define (process-command command)
   (if (< (length command) 4) ;; At least dir, socket, action and service.
       (local-output "Invalid command.")
-      (let ((dir (car command))
-	    (file (cadr command))
-	    (action (string->symbol (caddr command)))
-	    (service (string->symbol (cadddr command)))
-	    (args (cddddr command)))
-	(chdir dir)
-	(and file
-	     (open-extra-sender file))
-	;; We have to catch `quit' so that we can send the
-	;; terminator line to deco before we actually quit.
-	(catch 'quit
-	       (lambda ()
-		 (case action
-		   ((start) (apply start service args))
-		   ((stop) (apply stop service args))
-		   ((enforce) (apply enforce service args))
-		   ((list-actions) (display-extra-actions service))
-		   ;; `enable' and `disable' have the semantics of
-		   ;; `extra-action', thus they are handled there.
-		   (else (apply extra-action
-				(cons* service action args)))))
-	       (lambda (key)
-		 (and file
-		      (close-extra-sender))
-		 (quit)))
-	(and file
-	     (close-extra-sender)))))
+    (let ((dir (car command))
+	  (file (cadr command))
+	  (the-action (string->symbol (caddr command)))
+	  (service-symbol (string->symbol (cadddr command)))
+	  (args (cddddr command)))
+      (chdir dir)
+      (and file
+	   (open-extra-sender file))
+      ;; We have to catch `quit' so that we can send the terminator
+      ;; line to deco before we actually quit.
+      (catch 'quit
+	(lambda ()
+	  (case the-action
+	    ((start) (apply start service-symbol args))
+	    ((stop) (apply stop service-symbol args))
+	    ((enforce) (apply enforce service-symbol args))
+	    ((dmd-status)
+	     (if (not (null? args))
+		 (local-output "Too many arguments.")
+	       (let ((target-services (lookup-running-or-providing
+				       service-symbol)))
+		 (if (null? target-services)
+		     (handle-unknown service-symbol 'action the-action args)
+		   (for-each dmd-status
+			     target-services)))))
+	    ;; Actions which have the semantics of `action' are
+	    ;; handled there.
+	    (else (apply action service-symbol the-action args))))
+	(lambda (key)
+	  (and file
+	       (close-extra-sender))
+	  (quit)))
+      (and file
+	   (close-extra-sender)))))
 
 (main (cdr (command-line)))
diff -urN dmd--0.7/dmd.texi dmd--0.5/dmd.texi
--- dmd--0.7/dmd.texi	2003-04-02 20:49:17.000000000 +0200
+++ dmd--0.5/dmd.texi	2003-04-16 20:53:31.000000000 +0200
@@ -4,7 +4,7 @@
 @settitle dmd Manual
 
 @include version.texi
-@set YEARS 2002
+@set YEARS 2002, 2003
 
 @dircategory System software
 @direntry
@@ -278,8 +278,8 @@
 is called @dfn{deco}, the @dfn{DaEmon COntroller}@footnote{Some people
 might argue that it actually is short for ``decoration'', indicating
 that it is useless. :-)}.  To perform an action, like stopping a
-service or calling an extra-action of a service, you use the deco
-program.  It will communicate with dmd over a Unix Domain Socket.
+service or calling an action of a service, you use the deco program.
+It will communicate with dmd over a Unix Domain Socket.
 
 Thus, you start dmd once, and then always use deco whenever you want
 to do something service-related.  Since deco passes its current
@@ -332,7 +332,6 @@
 
 @item -p [@var{file}]
 @itemx --persistency[=@var{file}]
-Undocumented
 @c FIXME-CRITICAL
 
 @item -S
@@ -504,15 +503,14 @@
 returns @code{#f} and performs no further actions.
 
 @item
-@vindex extra-actions (slot of <service>)
-@cindex Addition actions of services
-@cindex Extra actions of services
-@code{extra-actions} specifies the additional actions that can be
-performed on a service when it is running.  A typical example for this
-is the @code{restart} action.  The macro @code{make-extra-actions}
-@ref{Service Convenience} is provided to abstract the actual data
-representation format for this slot.  (It actually is a hash
-currently.)
+@vindex actions (slot of <service>)
+@cindex Actions of services
+@cindex Service actions
+@code{actions} specifies the additional actions that can be performed
+on a service when it is running.  A typical example for this is the
+@code{restart} action.  The macro @code{make-actions} @ref{Service
+Convenience} is provided to abstract the actual data representation
+format for this slot.  (It actually is a hash currently.)
 
 @item
 @vindex enabled? (slot of <service>)
@@ -577,10 +575,10 @@
 value, thus @code{#f} if the service was stopped.
 @end deffn
 
-@deffn {method} extra-action (obj <service>) action . args
-Calls the extra-action @var{action} (a symbol) of the service
-@var{obj}, with the specified @var{args}, which are dependend on the
-particular extra-action.
+@deffn {method} action (obj <service>) the-action . args
+Calls the action @var{the-action} (a symbol) of the service @var{obj},
+with the specified @var{args}, which have a meaning depending on the
+particular action.
 @end deffn
 
 @deffn {method} conflicts-with (obj <service>)
@@ -612,9 +610,9 @@
 
 @deffn {method} default-display-status (obj <service>)
 Display status information about @var{obj}.  This method is called
-when the user performs the extra-action @code{status} on @var{obj},
-but there is no specific implementation given for it.  It is also
-called when @code{detailed-status} is applied on @code{dmd}.
+when the user performs the action @code{status} on @var{obj}, but
+there is no specific implementation given for it.  It is also called
+when @code{detailed-status} is applied on @code{dmd}.
 @end deffn
 
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -636,12 +634,12 @@
 @var{name}.
 @end deffn
 
-@deffn {macro} make-extra-actions (name proc) ...
-This macro is used to create a value for the @code{extra-actions} slot
-of a service object @ref{Slots of services}.  Each @var{name} is a
-symbol and each @var{proc} the corresponding procedure that will be
-called to perform the action.  A @var{proc} has one argument, which
-will be the current value of the @code{running} slot of the service.
+@deffn {macro} make-actions (name proc) ...
+This macro is used to create a value for the @code{actions} slot of a
+service object @ref{Slots of services}.  Each @var{name} is a symbol
+and each @var{proc} the corresponding procedure that will be called to
+perform the action.  A @var{proc} has one argument, which will be the
+current value of the @code{running} slot of the service.
 @end deffn
 
 @deffn {method} start (obj <symbol>)
@@ -652,9 +650,9 @@
 Stop a registered service providing @var{obj}.
 @end deffn
 
-@deffn {method} extra-action (obj <symbol>) action . args
-The same as the @code{extra-action} method of class @code{<service>},
-but uses a service that provides @var{obj} and is running.
+@deffn {method} action (obj <symbol>) the-action . args
+The same as the @code{action} method of class @code{<service>}, but
+uses a service that provides @var{obj} and is running.
 @end deffn
 
 @deffn {procedure} for-each-service proc
@@ -739,9 +737,9 @@
         #:requires '()
         #:start (...)
         #:stop (...)
-        #:extra-actions (make-extra-actions
-                          (reload-modules (...))
-                          (restart (...)))))
+        #:actions (make-actions
+                   (reload-modules (...))
+                   (restart (...)))))
 @end lisp
 
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -752,7 +750,7 @@
 @cindex dmd service
 @cindex special services
 The service @code{dmd} is special, because it is used to control dmd
-itself.  It provides the following extra-actions (in addition to
+itself.  It provides the following actions (in addition to
 @code{enable}, @code{disable} and @code{restart} which do not make
 sense here).
 
@@ -937,6 +935,7 @@
 some testing.
 
 @menu
+* Coding standards::    How to properly hack dmd.
 * Design decisions::    Why dmd is what it is.
 * Service Internals::   How services actually work.
 * Runlevel evolution::  Learning from past mistakes.
@@ -944,6 +943,24 @@
 
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
+@node Coding standards
+@section Coding standards
+
+About formatting: Use common sense and GNU Emacs (which actually is
+the same, of course), and you almost can't get the formatting wrong.
+Notable exceptions: Indent @code{if} like it is done in ELisp, and
+@code{catch} also deserves a better indenting.  This can be achieved
+by putting this in your @code{~/.emacs}:
+
+@lisp
+(put 'if 'scheme-indent-function 2)
+(put 'catch 'scheme-indent-function 1)
+@end lisp
+
+This section will be extended in the future...
+
+@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
 @node Design decisions
 @section Design decisions
 
@@ -1052,12 +1069,11 @@
 what needs to be done whenever starting a service fails, also marking
 that particular service as unstartable, except if it fails to start
 because a dependency could not be resolved (or maybe even then?).
-This is even more complicated (and somehow smells for @code{call/cc},
-don't you think?).  Instead of implementing this and thereby producing
-code that (a) nobody understands, (b) certainly has a lot of bugs, (c)
-will be unmaintainable and (d) causes users to panic because they
-won't understand what will happen, I decided to do the following
-instead:
+This is even more complicated.  Instead of implementing this and
+thereby producing code that (a) nobody understands, (b) certainly has
+a lot of bugs, (c) will be unmaintainable and (d) causes users to
+panic because they won't understand what will happen, I decided to do
+the following instead:
 
 @item
 Just report the error, and let the user fix it (in this case, fix the
@@ -1098,8 +1114,7 @@
 @menu
 * Runlevel assumptions::    What runlevels should be like
 * Runlevels - part one::    The first attempts of making it work
-* Runlevels - part two::    A more promising attempt
-* Runlevels - part three::  It should work... somehow...
+* Runlevels - part two::    It should work... somehow...
 @end menu
 
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1145,15 +1160,8 @@
 @node Runlevels - part one
 @subsection Runlevels, part one
 
-@c FIXME-CRITICAL
-
-@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@node Runlevels - part two
-@subsection Runlevels, part two
-
-I came up with the following algorithm (here in Pseudo-Scheme), which
-is possibly slightly buggy, but should give you the idea:
+I came up with the following method (here in Pseudo-Scheme), which is
+possibly slightly buggy, but should give you the idea:
 
 @lisp
 ;; Beginning with the canonical names in CURRENT-SERVICES, start and
@@ -1243,8 +1251,8 @@
 
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
-@node Runlevels - part three
-@subsection Runlevels, part three
+@node Runlevels - part two
+@subsection Runlevels, part two
 
 Let's look again at the table at the end of part two:
 
@@ -1291,7 +1299,7 @@
 services are running already).  This also reduces the amount of
 possible combinations a lot.  So what remains after that are the
 services we might need for fulfilling dependencies.  For them, we
-could to try all combinations (2^n), making sure that we always try
+could try all combinations (2^n), making sure that we always try
 subsets before any of their supersets to avoid starting unneeded
 services.  We should take into account which services are already
 running as well.
diff -urN dmd--0.7/examples/Makefile.am dmd--0.5/examples/Makefile.am
--- dmd--0.7/examples/Makefile.am	2002-10-10 19:35:36.000000000 +0200
+++ dmd--0.5/examples/Makefile.am	2003-03-08 06:22:40.000000000 +0100
@@ -1,3 +1,3 @@
 # examples/Makefile.am -- Add a few examples to the distribution.
 
-EXTRA_DIST = README wolfgangj.scm
+EXTRA_DIST = README _unknown.scm wolfgangj.scm
diff -urN dmd--0.7/examples/Makefile.in dmd--0.5/examples/Makefile.in
--- dmd--0.7/examples/Makefile.in	2002-10-12 15:40:49.000000000 +0200
+++ dmd--0.5/examples/Makefile.in	2003-04-08 17:09:08.000000000 +0200
@@ -68,6 +68,12 @@
 AMTAR = @AMTAR@
 AWK = @AWK@
 DEPDIR = @DEPDIR@
+GUILE = @GUILE@
+GUILE_CFLAGS = @GUILE_CFLAGS@
+GUILE_CONFIG = @GUILE_CONFIG@
+GUILE_LDFLAGS = @GUILE_LDFLAGS@
+GUILE_SITE = @GUILE_SITE@
+GUILE_TOOLS = @GUILE_TOOLS@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 PACKAGE = @PACKAGE@
 STRIP = @STRIP@
@@ -76,7 +82,7 @@
 am__quote = @am__quote@
 install_sh = @install_sh@
 
-EXTRA_DIST = README wolfgangj.scm
+EXTRA_DIST = README _unknown.scm wolfgangj.scm
 subdir = examples
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_CLEAN_FILES =
diff -urN dmd--0.7/examples/README dmd--0.5/examples/README
--- dmd--0.7/examples/README	2002-11-08 14:09:20.000000000 +0100
+++ dmd--0.5/examples/README	2003-03-08 06:31:14.000000000 +0100
@@ -1,13 +1,17 @@
 Example configurations for dmd
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
-This directory contains personal configuration files.  You can send me
-your configuration too, and I will include it here, provided that it
-is available under a license that makes it Free Software.
+This directory contains personal configuration files and interesting
+configuration possibilities, the latter being in the files starting
+with an underscore character.  You can send me your configuration too
+(or your cute configuration code snippets), and I will include it
+here, provided that it is available under a license that makes it Free
+Software.  Note that for personal configurations I don't want
+ChangeLogs, since I won't maintain your configuration anyway :-) but
+changes in the snippets should be documented like other changes.
 
 Hint: If you send my your configuration, then not only can other
 people learn from it, but I can also make sure that I do not break
 your code too often by making incompatible changes, and if I do it
 anyway but notice it, I might tell you how to change the code to work
 with a new version.
-
diff -urN dmd--0.7/examples/_unknown.scm dmd--0.5/examples/_unknown.scm
--- dmd--0.7/examples/_unknown.scm	1970-01-01 01:00:00.000000000 +0100
+++ dmd--0.5/examples/_unknown.scm	2003-04-21 15:14:19.000000000 +0200
@@ -0,0 +1,153 @@
+;; _unknown.scm -- An example for an `unknown' service.
+;; Copyright (C) 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
+;;
+;; This 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, or (at your option)
+;; any later version.
+;;
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA  02111-1307, USA.
+
+;; Return true if STR1 lacks a character that exists in STR2, but
+;; otherwise both are identical.
+(define (lacks-char-from? str1 str2)
+  (and (= (string-length str1)
+	  (+ (string-length str2) 1))
+       (letrec ((next
+		 (lambda (pos)
+		   (and (not (= pos (string-length str1)))
+			(or (string=? str2
+				      (string-append
+				       (substring str1 0 pos)
+				       (substring str1
+						  (+ pos 1)
+						  (string-length str1))))
+			    (next (+ pos 1)))))))
+	 (next 0))))
+
+;; Return true if either of STR1 and STR2 lacks a character found in
+;; the other one, but otherwise both are identical (e.g. as is the
+;; case for "blah" and "bla").
+(define (differs-by-missing-char? str1 str2)
+  (or (lacks-char-from? str1 str2)
+      (lacks-char-from? str2 str1)))
+
+;; Return true if the only difference between STR1 and STR2 is that a
+;; successive pair of characters is switched in one of them.
+(define (differs-by-switched-chars? str1 str2)
+  (and (= (string-length str1)
+	  (string-length str2))
+       (> (string-length str1) 1)
+       (letrec ((next
+		 (lambda (pos)
+		   (and (not (= pos (string-length str1)))
+			(or (string=? str2
+				      (string-append
+				       (substring str1 0 (- pos 1))
+				       (string (string-ref str1 pos)
+					       (string-ref str1 (- pos 1)))
+				       (substring str1
+						  (+ pos 1)
+						  (string-length str1))))
+			    (next (+ pos 1)))))))
+	 (next 1))))
+
+;; Return true if they differ by exactly one character (e.g. as is the
+;; case for "blah" and "bleh"), if it isn't the only one.
+(define (differs-by-one-char? str1 str2)  
+  (and (= (string-length str1)
+	  (string-length str2))
+       (> (string-length str1) 1)
+       (letrec ((next
+		 (lambda (pos found-difference)
+		   (if (= pos (string-length str1))
+		       found-difference
+		       (if (char=? (string-ref str1 pos)
+				   (string-ref str2 pos))
+			   (next (+ pos 1) found-difference)
+			   (and (not found-difference)
+				(next (+ pos 1) #t)))))))
+	 (next 0 #f))))
+
+;; Return true if STR1 and STR2 are identical, except for case
+;; (e.g. this gives true for "foobar" and "FooBAR").
+(define (differs-only-in-case? str1 str2)
+  (and (not (string=? str1 str2))
+       (string-ci=? str1 str2)))
+
+;; Return true if STR1 and STR2 are `similar' strings, meaning that
+;; they only differ in a minor way.
+(define (similar? str1 str2)
+  (any (lambda (pred?)
+	 (pred? str1 str2))
+       (list differs-by-missing-char?
+	     differs-by-switched-chars?
+	     differs-by-one-char?
+	     differs-only-in-case?)))
+
+
+
+;; TODO
+;;  - We could look for non-running services first on `start' etc.
+;;  - We also should do `unknown-action' (if service is known)
+;;    - If doing this, we should enable the service to handle it
+;;  - Make this the `default unknown service'
+;;  - Messages if nothing found.
+
+;; Suggest a service that satisfies PRED?, if given, and has a name
+;; similar to SERVICE-SYMBOL.
+(define look-for-service
+  (case-lambda
+   ((service-symbol) (look-for-service service-symbol (lambda (x) #t)))
+   ((service-symbol pred?)
+    (call/ec
+     (lambda (return)
+       (for-each-service
+	(lambda (s)
+	  (and (pred? s)
+	       (similar? (symbol->string service-symbol)
+			 (symbol->string (canonical-name s)))
+	       (begin
+		 (format #t "Did you mean ~a maybe?" (canonical-name s))
+		 (newline)
+		 (return #t)))))
+       #f)))))
+
+;; The classical compose.
+(define (compose f g)
+  (lambda (x)
+    (f (g x)))
+
+(define unknown-service
+  (make <service>
+    #:provides '(unknown)
+    #:actions (make-actions
+	       (start
+		"Called if user wants to start an unknown service."
+		(lambda (running service-sym . args)
+		  (or (look-for-service service-sym (compose not running?))
+		      (look-for-service service-sym))
+		  running))
+	       (stop
+		"Called if user wants to stop an unknown service."
+		(lambda (running service-sym . args)
+		  (or (look-for-service service-sym running?)
+		      (look-for-service service-sym))
+		  running))
+	       (action
+		"Called if user frobs an unknown service."
+		(lambda (running service-sym the-action . args)
+		  (or (look-for-service service-sym running?)
+		      (look-for-service service-sym))
+		  running)))))
+
+(register-services unknown-service)
+(start unknown-service)
diff -urN dmd--0.7/examples/wolfgangj.scm dmd--0.5/examples/wolfgangj.scm
--- dmd--0.7/examples/wolfgangj.scm	2002-12-20 18:55:39.000000000 +0100
+++ dmd--0.5/examples/wolfgangj.scm	2003-04-16 21:12:30.000000000 +0200
@@ -1,5 +1,5 @@
 ;; wolfgangj.scm -- Personal dmd configuration of Wolfgang Jährling.
-;; Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;;
 ;; This is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -68,23 +68,23 @@
 
 ;; Add a new terminal to the list of registered services.
 (define (add-new-term)
-  (set! term-counter (1+ term-counter))
+  (set! term-counter (+ term-counter 1))
   (register-services (make-term term-counter)))
 
 (register-services
  (make <service>
    #:provides '(term)
-   #:extra-actions (make-extra-actions
-		    (create
-		     (lambda (running)
-		       (add-new-term)))
-		    (counter-set
-		     (lambda (running num)
-		       (set! term-counter (string->number num))))
-		    (status
-		     (lambda (running)
-		       (local-output "Terminal counter is at ~a."
-				     term-counter)))))
+   #:actions (make-actions
+	      (create "Create a new terminal."
+	       (lambda (running)
+		 (add-new-term)))
+	      (counter-set "Set the terminal creation counter."
+	       (lambda (running num)
+		 (set! term-counter (string->number num))))
+	      (status "Display the terminal creation counter."
+	       (lambda (running)
+		 (local-output "Terminal counter is at ~a."
+			       term-counter)))))
  (make <service>
    #:provides '(apache insecurity)
    #:requires '(local-net)
@@ -94,15 +94,15 @@
    #:provides '(inet insecurity)
    #:start (make-system-constructor inet " start")
    #:stop (make-system-destructor inet " stop")
-   #:extra-actions (make-extra-actions
-		    (dial
-		     (lambda (running)
-		       ((make-system-constructor inet-dial))
-		       #t))
-		    (hangup
-		     (lambda (running)
-		       ((make-system-constructor inet-hangup))
-		       #t))))
+   #:actions (make-actions
+	      (dial "Connect to the big, evil internet."
+	       (lambda (running)
+		 (system inet-dial)
+		 #t))
+	      (hangup "Cut the internet connection."
+	       (lambda (running)
+		 (system inet-hangup)
+		 #t))))
  (make <service>
    #:provides '(local-net)
    #:start (make-system-constructor ifconfig " " local-interface " " local-ip)
@@ -122,11 +122,11 @@
   (loop default-terms))
 
 ;; Go into background.
-(extra-action 'dmd 'daemonize)
+(action 'dmd 'daemonize)
 
 ;; Setup internet, a mailer and a few terms.
 (for-each start
-	  (append! '(term inet mailer-daemon)
-		   (map (lambda (x)
-			  (symbol-append 'term- (number->symbol x)))
-			(iota default-terms 1))))
+	  (append '(term inet mailer-daemon)
+		  (map (lambda (x)
+			 (symbol-append 'term- (number->symbol x)))
+		       (iota default-terms 1))))
diff -urN dmd--0.7/runlevel.scm dmd--0.5/runlevel.scm
--- dmd--0.7/runlevel.scm	2003-01-01 15:18:59.000000000 +0100
+++ dmd--0.5/runlevel.scm	2003-04-21 14:30:54.000000000 +0200
@@ -25,6 +25,9 @@
 ;; current into the desired state.  I have an idea how to implement it
 ;; though.  See the Texinfo manual for details.
 
+;; FIXME: Hmm... just a thought: It might be _much_ easier to
+;; implement if the selectors return what they want to start and stop.
+
 ;; The actual code below is not finished.
 
 ;; An abstract runlevel.
@@ -43,7 +46,8 @@
 				   services)))))
       services))
 
-  ;; Return the canonical names of SERVICES, but with dependencies added.
+  ;; Return the canonical names of SERVICES, but with dependencies
+  ;; added.
   (define (canonical-with-dependencies services)
     ;; FIXME: Hmmm... conflicting services..?  If A and B both provide
     ;; X and Y, and C depends on X, D depends on Y, we might fail very
diff -urN dmd--0.7/self.scm dmd--0.5/self.scm
--- dmd--0.7/self.scm	2003-02-20 18:17:43.000000000 +0100
+++ dmd--0.5/self.scm	2003-05-01 22:20:22.000000000 +0200
@@ -1,5 +1,5 @@
 ;; self.scm -- Definition of the `dmd' service.
-;; Copyright (C) 2002 Wolfgang Jährling <wolfgang@pro-linux.de>
+;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;;
 ;; This is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -18,14 +18,15 @@
 
 (define dmd-service
   (make <service>
+    #:docstring "The dmd service is used to operate on dmd itself."
     #:provides '(dmd)
     #:requires '()
     #:respawn #f
-    #:start (lambda ()
+    #:start (lambda args
 	      (and (isatty? (current-output-port))
 		   (display-version))
 	      #t)
-    #:stop (lambda (unused)
+    #:stop (lambda (unused . args)
 	     (local-output "Exiting dmd...")
 	     ;; Prevent that we try to stop ourself again.
 	     (slot-set! dmd-service 'running #f)
@@ -44,63 +45,86 @@
 		    (write-line running-services
 				(open-output-file persistency-state-file))))
 	     (quit))
-    ;; All extra-actions need to take care that they do not invoke any
+    ;; All actions here need to take care that they do not invoke any
     ;; user-defined code without catching `quit', since they are
-    ;; allowed to quit.
-    #:extra-actions (make-extra-actions
-		     ;; Display status.
-		     (status
-		      (lambda (running)
-			(let ((started '()) (stopped '()))
-			  (for-each-service
-			   (lambda (service)
-			     (if (running? service)
-				 (set! started (cons (canonical-name service)
-						     started))
-				 (set! stopped (cons (canonical-name service)
-						     stopped)))))
-			  (local-output "Started: ~a" started)
-			  (local-output "Stopped: ~a" stopped))))
-		     ;; Look at every service in detail.
-		     (detailed-status
-		      (lambda (running)
-			(for-each-service default-display-status)))
-		     ;; Load a configuration file.
-		     (load
-		      (lambda (running file-name)
-			(local-output "Loading ~a." file-name)
-			;; Every extra-action is protected anyway, so
-			;; no need for a `catch' here.
-			(load file-name)))
-		     ;; Disable output.
-		     (silent
-		      (lambda (running)
-			(be-silent)))
-		     ;; Enable output.
-		     (verbose
-		      (lambda (running)
-			(be-verbose)))
-		     ;; Go into background.  This should be called
-		     ;; before respawnable services are started, as
-		     ;; otherwise we would not get the SIGCHLD signals
-		     ;; when they terminate.
-		     (daemonize
-		      (lambda (running)
-			(be-silent)
-			(if (zero? (primitive-fork))
-			    #t
-			    (quit))))
-		     (enable-persistency
-		      (lambda (running)
-			(set! persistency #t)))
-		     (disable-persistency
-		      (lambda (running)
-			(set! persistency #f)))
-		     ;; Restart it - that does not make sense, but
-		     ;; we're better off by implementing it due to the
-		     ;; default action.
-		     (restart
-		      (lambda (running)
-			(local-output "You must be kidding."))))))
+    ;; allowed to quit, while user-supplied code shouldn't be.
+    #:actions
+    (make-actions
+     ;; Display status.
+     (status
+      "Display the status of dmd.  I.e. which services are running and
+which ones are not."
+      (lambda (running)
+	(let ((started '()) (stopped '()))
+	  (for-each-service
+	   (lambda (service)
+	     (if (running? service)
+		 (set! started (cons (canonical-name service)
+				     started))
+	       (set! stopped (cons (canonical-name service)
+				   stopped)))))
+	  (local-output "Started: ~a" started)
+	  (local-output "Stopped: ~a" stopped))))
+     ;; Look at every service in detail.
+     (detailed-status
+      "Display detailed information about all services."
+      (lambda (running)
+	(for-each-service dmd-status)))
+     ;; Load a configuration file.
+     (load
+      "Load the Scheme code from FILE into dmd.  This is potentially
+dangerous.  You have been warned."
+      (lambda (running file-name)
+	(local-output "Loading ~a." file-name)
+	;; Every action is protected anyway, so no need for a `catch'
+	;; here.  FIXME: What about `quit'?
+	(load file-name)))
+     ;; Disable output.
+     (silent
+      "Disable the displaying of information on standard output."
+      (lambda (running)
+	(be-silent)))
+     ;; Enable output.
+     (verbose
+      "Enable the displaying of information on standard output."
+      (lambda (running)
+	(be-verbose)))
+     ;; Go into the background.
+     (daemonize
+      "Go into the background.  Be careful, this means that a new
+process will be created, so dmd will not get SIGCHLD signals anymore
+if previously spawned childs terminate.  Therefore, this action should
+usually only be used (if at all) *before* childs get spawned for which
+we want to receive these signals."
+      (lambda (running)
+	(be-silent)
+	(if (zero? (primitive-fork))
+	    #t
+	  (quit))))
+     (persistency
+      "Safe the current state of running and non-running services.
+This status gets written into a file on termination, so that we can
+restore the status on next startup.  Optionally, you can pass a file
+name as argument that will be used to store the status."
+      (opt-lambda (running) ((file #f))
+	(set! persistency #t)
+	(and file
+	     (set! persistency-state-file file))))
+     (no-persistency
+      "Don't safe state in a file on exit."
+      (lambda (running)
+	(set! persistency #f)))
+     (cd
+      "Change the working directory of dmd.  This only makes sense
+when in interactive mode, i.e. with `--socket=none'."
+      (lambda (running dir)
+	(chdir dir)))
+     ;; Restart it - that does not make sense, but
+     ;; we're better off by implementing it due to the
+     ;; default action.
+     (restart
+      "This does not work for dmd."
+      (lambda (running)
+	(local-output "You must be kidding."))))))
 
 (register-services dmd-service)
diff -urN dmd--0.7/service.scm dmd--0.5/service.scm
--- dmd--0.7/service.scm	2003-03-23 16:22:13.000000000 +0100
+++ dmd--0.5/service.scm	2003-05-01 23:35:40.000000000 +0200
@@ -20,11 +20,11 @@
 (define respawn-limit (cons 5 5))
 
 (define-class <service> ()
-  ;; List of provided service symbols.  The first one is also called
+  ;; List of provided service-symbols.  The first one is also called
   ;; the `canonical name' and must be unique to this service.
   (provides #:init-keyword #:provides
 	    #:getter provided-by)
-  ;; List of required service symbols.
+  ;; List of required service-symbols.
   (requires #:init-keyword #:requires
 	    #:init-value '()
 	    #:getter required-by)
@@ -39,23 +39,27 @@
   ;; starting attempt failed, it must return `#f'.  The return value
   ;; will be stored in the `running' slot.
   (start #:init-keyword #:start
-	 #:init-value (lambda args #t))
+	 #:init-value (lambda () #t))
   ;; The action to perform to stop the service.  This must be a
   ;; procedure and may take an arbitrary amount of arguments, but must
   ;; be callable with exactly one argument, which will be the value of
-  ;; the `running' slot.  Whatever the procedure returns will be saved
-  ;; in the `running' slot again, thus it should return `#f' on
-  ;; success (and possibly even on failure).
+  ;; the `running' slot.  Whatever the procedure returns will be
+  ;; ignored.
   (stop #:init-keyword #:stop
-	#:init-value (lambda (running . args) #f))
+	#:init-value (lambda (running) #f))
   ;; Additional actions that can be performed with the service.  This
-  ;; is a hash with a procedure as the value for every action symbol.
-  (extra-actions #:init-keyword #:extra-actions
-		 #:init-form (make-extra-actions))
+  ;; currently is a list with each element (and thus each action)
+  ;; being ``(name . (proc . docstring))'', but users should not rely
+  ;; on this.
+  (actions #:init-keyword #:actions
+	   #:init-form (make-actions))
   ;; If this is `#f', it means that the service is not running
   ;; currently.  Otherwise, it is the value that was returned by the
   ;; procedure in the `start' slot when the service was started.
   (running #:init-value #f)
+  ;; A description of the service.
+  (docstring #:init-keyword #:docstring
+	     #:init-value "[No description].")
   ;; A service can be disabled if it is respawning too fast; it is
   ;; also possible to enable or disable it manually.
   (enabled? #:init-value #t
@@ -72,6 +76,10 @@
   (last-respawns #:init-form (apply circular-list
 				    (make-list (car respawn-limit) 0))))
 
+(define action:name car)
+(define action:proc cadr)
+(define action:doc cddr)
+
 ;; Return the canonical name of the service.
 (define-method (canonical-name (obj <service>))
   (car (provided-by obj)))
@@ -80,16 +88,20 @@
 (define-method (running? (obj <service>))
   (and (slot-ref obj 'running) #t))
 
-;; Return a list of all extra-actions implemented by OBJ. 
-(define-method (extra-action-list (obj <service>))
-  (hash-fold (lambda (key value all)
-	       (cons key all))
-	     '()
-	     (slot-ref obj 'extra-actions)))
-
-;; Return whether OBJ implements the extra-action ACTION.
-(define-method (defines-extra-action? (obj <service>) action)
-  (and (hashq-ref (slot-ref obj 'extra-actions) action #f) #t))
+;; Return a list of all actions implemented by OBJ. 
+(define-method (action-list (obj <service>))
+  (map action:name (slot-ref obj 'actions)))
+
+;; Return the action ACTION.
+(define-method (lookup-action (obj <service>) action)
+  (define (car-if-pair x)
+    (if (pair? x) (car x) x))
+
+  (assq action (slot-ref obj 'actions)))
+
+;; Return whether OBJ implements the action ACTION.
+(define-method (defines-action? (obj <service>) action)
+  (and (lookup-action obj action) #t))
 
 ;; Enable the service, allow it to get started.
 (define-method (enable (obj <service>))
@@ -105,18 +117,16 @@
 (define-method (start (obj <service>) . args)
   (cond ((running? obj)
 	 (local-output "Service ~a is already running."
-		       (canonical-name obj))
-	 #f) ;; FIXME: Is that the right thing?
+		       (canonical-name obj)))
 	((not (enabled? obj))
 	 (local-output "Service ~a is currently disabled."
-		       (canonical-name obj))
-	 #f)
+		       (canonical-name obj)))
 	((let ((conflicts (conflicts-with-running obj)))
 	   (or (null? conflicts)
 	       (local-output "Service ~a conflicts with running services ~a."
 			     (canonical-name obj) conflicts))
 	   (not (null? conflicts)))
-	 #f)
+	 #f) ;; Dummy.
 	(else
 	 ;; It is not running and does not conflict with anything
 	 ;; that's running, so we can go on and launch it.
@@ -133,18 +143,18 @@
 	       (local-output "Service ~a depends on ~a."
 			     (canonical-name obj)
 			     problem)
-	       ;; Start the service itself.
-	       (slot-set! obj 'running (catch #t
-					       (lambda ()
-						 (apply (slot-ref obj 'start)
-							args))
-					       (lambda (key . args)
-						 (caught-error key args)
-						 #f))))
+	     ;; Start the service itself.
+	     (slot-set! obj 'running (catch #t
+				       (lambda ()
+					 (apply (slot-ref obj 'start)
+						args))
+				       (lambda (key . args)
+					 (caught-error key args)
+					 #f))))
 	   ;; Status message.
 	   (local-output (if (running? obj)
 			     (l10n "Service ~a has been started.")
-			     (l10n "Service ~a could not be started."))
+			   (l10n "Service ~a could not be started."))
 			 (canonical-name obj)))))
   (slot-ref obj 'running))
 
@@ -153,81 +163,130 @@
 (define-method (stop (obj <service>) . args)
   (if (not (running? obj))
       (local-output "Service ~a is not running." (canonical-name obj))
-      (if (slot-ref obj 'stop-delay?)
-	  (begin
-	    (slot-set! obj 'waiting-for-termination? #t)
-	    (local-output "Service ~a pending to be stopped."
-			  (canonical-name obj)))
-	  (begin
-	    ;; Stop services that depend on it.
-	    (for-each-service
-	     (lambda (serv)
-	       (and (running? serv)
-		    (for-each (lambda (sym)
-				(and (memq sym (provided-by obj))
-				     (stop serv)))
-			      (required-by serv)))))
-	    ;; If it is a respawnable service, we have to pretend that
-	    ;; it is already stopped, because killing it in the
-	    ;; destructor would respawn it immediatelly otherwise.
-	    (and (respawn? obj)
-		 (slot-set! obj 'running #f))
-	    ;; Stop the service itself.
-	    (slot-set! obj 'running (catch #t
-					   (lambda ()
-					     (apply (slot-ref obj 'stop)
-						    (slot-ref obj 'running)
-						    args))
-					   (lambda (key . args)
-					     ;; Special case: `dmd' may quit.
-					     (and (eq? dmd-service obj)
-						  (eq? key 'quit)
-						  (apply quit args))
-					     (caught-error key args)
-					     ;; Don't change anything.
-					     (slot-ref obj 'running))))
-	    ;; Status message.
-	    (let ((name (canonical-name obj)))
-	      (if (running? obj)
-		  (local-output "Service ~a could not be stopped." name)
-		  (local-output "Service ~a has been stopped." name))))))
+    (if (slot-ref obj 'stop-delay?)
+	(begin
+	  (slot-set! obj 'waiting-for-termination? #t)
+	  (local-output "Service ~a pending to be stopped."
+			(canonical-name obj)))
+      (begin
+	;; Stop services that depend on it.
+	(for-each-service
+	 (lambda (serv)
+	   (and (running? serv)
+		(for-each (lambda (sym)
+			    (and (memq sym (provided-by obj))
+				 (stop serv)))
+			  (required-by serv)))))
+
+	(let ((running-value (slot-ref obj 'running)))
+	  ;; If it is a respawnable service, we have to pretend that
+	  ;; it is already stopped, because killing it in the
+	  ;; destructor would respawn it immediatelly otherwise.
+	  ;; However, the destructor must be called with the original
+	  ;; value of the `running' slot.
+	  (and (respawn? obj)
+	       (slot-set! obj 'running #f))
+	  ;; Stop the service itself.
+	  (catch #t
+	    (lambda ()
+	      (apply (slot-ref obj 'stop)
+		     running-value
+		     args))
+	    (lambda (key . args)
+	      ;; Special case: `dmd' may quit.
+	      (and (eq? dmd-service obj)
+		   (eq? key 'quit)
+		   (apply quit args))
+	      (caught-error key args))))
+	;; Status message.
+	(let ((name (canonical-name obj)))
+	  (if (running? obj)
+	      (local-output "Service ~a could not be stopped." name)
+	    (local-output "Service ~a has been stopped." name))))))
   (slot-ref obj 'running))
 
-;; Call extra-action ACTION with ARGS.
-(define-method (extra-action (obj <service>) action . args)
-  (define (default-action running)
-    (case action
+;; Call action THE-ACTION with ARGS.
+(define-method (action (obj <service>) the-action . args)
+  (define (default-action running . args)
+    ;; All actions which are handled here might be called even if the
+    ;; service is not running, so they have to take this into account.
+    (case the-action
       ;; Restarting is done in the obvious way.
       ((restart)
-       (and running
-	    (stop obj))
+       (if running
+	   (stop obj)
+	 (local-output "~a was not running." (canonical-name obj)))
        (start obj))
-      ;; Displaying status via the default implementation.
       ((status)
-       (default-display-status obj))
+       (dmd-status obj))
       (else
+       ;; FIXME: Unknown service.
        (local-output "Service ~a does not have a ~a action."
 		     (canonical-name obj)
-		     action))))
+		     the-action))))
 
-  ;; Calling default-action will be allowed even when the service is
-  ;; not running, as it provides generally useful functionality and
-  ;; information.
-  (let ((proc (hashq-ref (slot-ref obj 'extra-actions)
-			 action
-			 default-action)))
+  (define (apply-if-pair obj proc)
+    (if (pair? obj)
+	(proc obj)
+      obj))
+
+  (let ((proc (or (apply-if-pair (lookup-action obj the-action)
+				 action:proc)
+		  default-action)))
+    ;; Calling default-action will be allowed even when the service is
+    ;; not running, as it provides generally useful functionality and
+    ;; information.
+    ;; FIXME: Why should the user-implementations not be allowed to be
+    ;; called this way?
     (if (and (not (eq? proc default-action))
 	     (not (running? obj)))
 	(local-output "Service ~a is not running." (canonical-name obj))
-	(catch #t
-	       (lambda ()
-		 (apply proc (slot-ref obj 'running) args))
-	       (lambda (key . args)
-		 ;; Special case: `dmd' may quit.
-		 (and (eq? dmd-service obj)
-		      (eq? key 'quit)
-		      (apply quit args))
-		 (caught-error key args))))))
+      (catch #t
+	(lambda ()
+	  (if (can-apply? proc (+ 1 (length args)))
+	      (apply proc (slot-ref obj 'running) args)
+	    ;; FIXME: Better message.
+	    (local-output "Action ~a of service ~a can't take ~a arguments."
+			  the-action (canonical-name obj) (length args))))
+	(lambda (key . args)
+	  ;; Special case: `dmd' may quit.
+	  (and (eq? dmd-service obj)
+	       (eq? key 'quit)
+	       (apply quit args))
+	  (caught-error key args))))))
+
+;; Display documentation about the service.
+(define-method (doc (obj <service>) . args)
+  (if (null? args)
+      ;; No further argument given -> Normal level of detail.
+      (local-output (slot-ref obj 'docstring))
+    (case (string->symbol (car args)) ;; Does not work with strings.
+      ((full)
+       ;; FIXME
+       (local-output (slot-ref obj 'docstring)))
+      ((short)
+       ;; FIXME
+       (local-output (slot-ref obj 'docstring)))
+      ((action)
+       ;; Display documentation of given actions.
+       (for-each
+	(lambda (the-action)
+	  (local-output "~a: ~a"
+			the-action
+			(let ((action-object
+			       (lookup-action obj
+					      (string->symbol the-action))))
+			  (if action-object
+			      (action:doc action-object)
+			    (i18n "This action does not exist.")))
+	(cdr args)))))
+      ((list-actions)
+       (local-output "~a ~a"
+		     (canonical-name obj)
+		     (action-list obj)))
+      (else
+       ;; FIXME: Implement doc-help.
+       (local-output "Unknown keyword.  Try `doc dmd help'.")))))
 
 ;; Return a list of canonical names of the services that conflict with
 ;; OBJ.
@@ -240,11 +299,9 @@
 			  (lookup-services sym)))
 	      (provided-by obj))
     ;; Clean up the result.
-    (set! conflicts
-	  (delete! (canonical-name obj)
-		   (delete-duplicates! conflicts eq?)
-		   eq?))
-    conflicts))
+    (delete! (canonical-name obj)
+	     (delete-duplicates! conflicts eq?)
+	     eq?)))
 
 ;; Check if this service provides a symbol that is already provided
 ;; by any other running services.  If so, return the canonical names
@@ -265,143 +322,169 @@
 ;; Start OBJ, but first kill all services which conflict with it.
 ;; FIXME-CRITICAL: Conflicts of indirect dependencies.  For this, we
 ;; seem to need a similar solution like launch-service.
+;; FIXME: This should rather be removed and added cleanly later.
 (define-method (enforce (obj <service>) . args)
   (for-each stop (conflicts-with-running obj))
   (apply start obj args))
 
 ;; Display information about the service.
-(define-method (default-display-status (obj <service>))
+(define-method (dmd-status (obj <service>))
   (local-output "Status of ~a:"
 		(canonical-name obj))
   (if (running? obj)
       (local-output "  It is started.")
-      (local-output "  It is stopped."))
+    (local-output "  It is stopped."))
   (if (enabled? obj)
       (local-output "  It is enabled.")
-      (local-output "  It is disabled."))
+    (local-output "  It is disabled."))
   (local-output "  Provides ~a." (provided-by obj))
   (local-output "  Requires ~a." (required-by obj))
   (local-output "  Conflicts with ~a." (conflicts-with obj))
   (if (respawn? obj)
       (local-output "  Will be respawned.")
-      (local-output "  Will not be respawned.")))
+    (local-output "  Will not be respawned.")))
 
 ;; Return whether OBJ requires something that is not yet running.
 (define-method (depends-resolved? (obj <service>))
   (call/ec (lambda (return)
 	     (for-each (lambda (dep)
-			 (or (find-running (lookup-services dep))
+			 (or (lookup-running dep)
 			     (return #f)))
 		       (required-by obj))
 	     #t)))
 
 
 
-;; Try to start service NAME with PROC.  Used by `start' and `enforce'.
+;; Try to start (with PROC) a service providing NAME.  Used by `start'
+;; and `enforce'.
 (define (launch-service name proc args)
   (let* ((possibilities (lookup-services name))
-	 (which (find-running possibilities)))
+	 (which (first-running possibilities)))
     (if (null? possibilities)
 	(local-output "No service provides ~a." name)
-	(or which
-	    ;; None running yet, start one.
-	    (set! which
-		  (call/ec (lambda (return)
-			     (for-each (lambda (service)
-					 (and (apply proc service args)
-					      (return service)))
-				       possibilities)
-			     #f)))))
+      (or which
+	  ;; None running yet, start one.
+	  (set! which
+		(call/ec (lambda (return)
+			   (for-each (lambda (service)
+				       (and (apply proc service args)
+					    (return service)))
+				     possibilities)
+			   #f)))))
     (or which
-	(let ((unknown (find-running (lookup-services 'unknown))))
+	(let ((unknown (lookup-running 'unknown)))
 	  (if (and unknown
-		   (defines-extra-action? unknown 'start))
-	      (apply extra-action unknown 'start name args)
-	      (local-output "Providing ~a impossible." name))))
+		   (defines-action? unknown 'start))
+	      (apply action unknown 'start name args)
+	    (local-output "Providing ~a impossible." name))))
     (and which #t)))
 
-;; Starting via symbol.
+;; Starting by name.
 (define-method (start (obj <symbol>) . args)
   (launch-service obj start args))
 
-;; Enforcing via symbol.
+;; Enforcing by name.  FIXME: Should be removed and added cleanly later.
 (define-method (enforce (obj <symbol>) . args)
   (launch-service obj enforce args))
 
-;; Stopping via symbol.
+;; Stopping by name.
 (define-method (stop (obj <symbol>) . args)
-  (let ((which (find-running (lookup-services obj))))
+  (let ((which (lookup-running obj)))
     (if (not which)
-	(let ((unknown (find-running (lookup-services 'unknown))))
+	(let ((unknown (lookup-running 'unknown)))
 	  (if (and unknown
-		   (defines-extra-action? unknown 'stop))
-	      (apply extra-action (car unknown) 'stop obj args)
-	      (local-output "No service currently providing ~a." obj)))
-	(apply stop which args))))
-
-;; Perform extra-action ACTION via symbol.
-(define-method (extra-action (obj <symbol>) action . args)
-  (let ((which
-	 ;; This is a list because we might apply the action on
-	 ;; multiple services.
-	 (list (find-running (lookup-services obj)))))
-    (and (not (car which))
-	 ;; None running, thus apply on all which provide it.
-	 (set! which (lookup-services obj)))
-    (if (null? which)
-	(let ((unknown (find-running (lookup-services 'unknown))))
+		   (defines-action? unknown 'stop))
+	      (apply action unknown 'stop obj args)
+	    (local-output "No service currently providing ~a." obj)))
+      (apply stop which args))))
+
+;; Perform action THE-ACTION by name.
+(define-method (action (obj <symbol>) the-action . args)
+  (let ((which-services (lookup-running-or-providing obj)))
+    (if (null? which-services)
+	(let ((unknown (lookup-running 'unknown)))
 	  (if (and unknown
-		   (defines-extra-action? unknown 'extra-action))
-	      (apply extra-action (car unknown) 'extra-action action args)
-	      (local-output "No service at all providing ~a." obj)))
-	(for-each (case action
-		    ((enable) enable)
-		    ((disable) disable)
-		    (else (lambda (serv)
-			    (apply extra-action serv action args))))
-		  which))))
-
-;; Display the names of all extra-actions of services providing OBJ.
-(define-method (display-extra-actions (obj <symbol>))
-  (if (null? (lookup-services obj))
-      (local-output "No service at all providing ~a." obj)
-      (for-each (lambda (serv)
-		  (local-output "~a ~a"
-				(canonical-name serv)
-				(extra-action-list serv)))
-		(lookup-services obj))))
+		   (defines-action? unknown 'action))
+	      (apply action unknown 'action the-action args)
+	    (local-output "No service at all providing ~a." obj)))
+      (for-each (lambda (s)
+		  (apply (case the-action
+			   ((enable) enable)
+			   ((disable) disable)
+			   ((doc) doc)
+			   (else
+			    (lambda (s . further-args)
+			      (apply action s the-action further-args))))
+			 s
+			 args))
+		which-services))))
 
 
 
-;;; Convenience facillities.
+;; Handling of unprovided service-symbols.  This can be called in
+;; either of the following ways (i.e. with either three or four
+;; arguments):
+;;   handle-unknown SERVICE-SYMBOL [ 'start | 'stop ] ARGS
+;;   handle-unknown SERVICE-SYMBOL 'action THE_ACTION ARGS
+(define (handle-unknown . args)
+  (let ((unknown (lookup-running 'unknown)))
+    ;; FIXME: Display message if no unknown service.
+    (if unknown
+	(apply-to-args args
+	    (case-lambda
+	     ;; Start or stop.
+	     ((service-symbol start/stop args)
+	      (if (defines-action? unknown start/stop)
+		  (apply action unknown start/stop service-symbol args)
+		;; FIXME: Bad message.
+		(local-output "Cannot ~a ~a." start/stop service-symbol)))
+	     ;; Action.
+	     ((service-symbol action-sym the-action args)
+	      (assert (eq? action-sym 'action))
+	      (if (defines-action? unknown 'action)
+		  (apply action unknown 'action service-symbol the-action args)
+		(local-output "No service provides ~a." service-symbol))))))))
 
 ;; Check if any of SERVICES is running.  If this is the case, return
 ;; it.  If none, return `#f'.  Only the first one found will be
 ;; returned; this is because this is mainly intended to be applied on
-;; the return value of `lookup-services'.
-(define (find-running services)
-  (call/ec (lambda (return)
-	     (for-each (lambda (serv)
-			 (and (running? serv)
-			      (return serv)))
-		       services)
-	     #f)))
+;; the return value of `lookup-services', where no more than one will
+;; ever run at the same time.
+(define (first-running services)
+  (find running? services))
+
+;; Return the running service that provides NAME, or false if none.
+(define (lookup-running name)
+  (first-running (lookup-services name)))
+
+;; Lookup the running service providing SYM, and return it as a
+;; one-element list.  If none is running, return a list of all
+;; services which provide SYM.
+(define (lookup-running-or-providing sym)
+  (define (list-unless-false x)
+    (if x (list x) x))
+
+  (or (list-unless-false (lookup-running sym))
+      (lookup-services sym)))
+
+;; FIXME: They ignore arguments currently, but they should not.
 
-;; Produce a constructor that execs PROGRAM with ARGS in a child
+;; Produce a constructor that execs PROGRAM with CHILD-ARGS in a child
 ;; process and returns its pid.
-(define (make-childexec-constructor program . args)
+(define (make-forkexec-constructor program . child-args)
   (lambda args
     (let ((pid (primitive-fork)))
       (if (zero? pid)
-          (apply execlp program program args)
-        pid))))
+	  (apply execlp program program child-args)
+	pid))))
 
 ;; Produce a destructor that sends SIGNAL to the process with the pid
-;; given as argument.
-(define (make-kill-destructor signal)
-  (lambda (pid . args)
-    (kill pid signal)
-    #f))
+;; given as argument, where SIGNAL defaults to `SIGTERM'.
+(define make-kill-destructor
+  (opt-lambda () ((signal SIGTERM))
+    (lambda (pid . args)
+      (kill pid signal)
+      #f)))
 
 ;; Produce a constructor that executes a command.
 (define (make-system-constructor . command)
@@ -418,24 +501,33 @@
 (define (make-init.d-service name . stuff)
   (let ((cmd (string-append "/etc/init.d/" name)))
     (apply make <service>
-           #:provides (list (string->symbol name))
-           #:start (make-system-constructor cmd " start")
-           #:stop (make-system-destructor cmd " stop")
-           stuff)))
-
-;; Conveniently create a hash table containing the extra-actions of a
-;; <service> object.
-(define-syntax-rule (make-extra-actions (NAME PROC) ...)
-  (let* ((actions-assoc (list (cons 'NAME PROC) ...))
-	 (actions (make-hash-table (length actions-assoc))))
-    (for-each (lambda (action-pair)
-		(hashq-set! actions (car action-pair) (cdr action-pair)))
-	      actions-assoc)
-    actions))
-
-;; A group of services which can be started and stopped together.  Not
-;; comparable with a real runlevel at all, but can be used to emulate
-;; a simple kind of runlevel.
+	   #:provides (list (string->symbol name))
+	   #:start (make-system-constructor cmd " start")
+	   #:stop (make-system-destructor cmd " stop")
+	   stuff)))
+
+;; Conveniently create an actions object containing the actions for a
+;; <service> object.  The current structure is a list of actions,
+;; where every action has the format ``(name . (proc . doc))''.
+(define-macro (make-actions . actions)
+  (if (null? actions)
+      ''()
+    `(cons (cons ',(caar actions)
+		 ;; The docstring in the middle is optional, which
+		 ;; makes this slightly more tricky.
+		 ,(case (length (car actions))
+		    ((2) `(cons ,(cadar actions)
+				"[No documentation.]"))
+		    ((3) `(cons ,(caddar actions)
+				,(cadar actions)))
+		    (else
+		     (error "Invalid syntax."))))
+	   (make-actions . ,(cdr actions)))))
+
+;; A group of service-names which can be provided (i.e. services
+;; providing them get started) and unprovided (same for stopping)
+;; together.  Not comparable with a real runlevel at all, but can be
+;; used to emulate a simple kind of runlevel.
 (define-syntax-rule (make-service-group NAME (SYM ...) ADDITIONS ...)
   (make <service>
     #:provides '(NAME)
@@ -500,22 +592,22 @@
 			  (slot-set! serv 'last-respawns
 				     (cdr (slot-ref serv 'last-respawns)))
 			  (start serv))
-			;; We have just been waiting for the
-			;; termination.  The `running' slot has
-			;; already been set to `#f' by `stop'.
-			(begin
-			  (local-output "Service ~a terminated."
-					(canonical-name serv))
-			  (slot-set! serv 'waiting-for-termination? #f)))
-		    (begin
-		      (local-output "Service ~a has been disabled."
-				    (canonical-name serv))
-		      (local-output "  (Respawning too fast.)")
-		      (slot-set! serv 'enabled? #f)))
+		      ;; We have just been waiting for the
+		      ;; termination.  The `running' slot has already
+		      ;; been set to `#f' by `stop'.
+		      (begin
+			(local-output "Service ~a terminated."
+				      (canonical-name serv))
+			(slot-set! serv 'waiting-for-termination? #f)))
+		  (begin
+		    (local-output "Service ~a has been disabled."
+				  (canonical-name serv))
+		    (local-output "  (Respawning too fast.)")
+		    (slot-set! serv 'enabled? #f)))
 		(return #t)))))))
 
   (without-extra-output
-   (without-system-error
+   (catch-system-error
     (call/ec handler))))
 
 ;; Install it as the handler.
@@ -528,9 +620,13 @@
     (assert (list-of-symbols? (provided-by new)))
     (assert (list-of-symbols? (required-by new)))
     (assert (boolean? (respawn? new)))
+    ;; Canonical name actually must be canonical.  (FIXME: This test
+    ;; is incomplete, since we may add a service later that makes it
+    ;; non-cannonical.)
+    (assert (null? (lookup-services (canonical-name new))))
     ;; FIXME: Verify consistency: Check that there are no circular
-    ;; dependencies, ensure that names are canonical(!), check for
-    ;; bogus conflicts/dependencies, whatever else makes sense.
+    ;; dependencies, check for bogus conflicts/dependencies, whatever
+    ;; else makes sense.
 
     ;; Insert into the hash table.
     (for-each (lambda (name)
diff -urN dmd--0.7/stamp-vti dmd--0.5/stamp-vti
--- dmd--0.7/stamp-vti	2003-02-20 17:10:57.000000000 +0100
+++ dmd--0.5/stamp-vti	2003-05-01 22:40:31.000000000 +0200
@@ -1,4 +1,4 @@
-@set UPDATED 17 February 2003
-@set UPDATED-MONTH February 2003
-@set EDITION -0.7
-@set VERSION -0.7
+@set UPDATED 16 April 2003
+@set UPDATED-MONTH April 2003
+@set EDITION -0.5
+@set VERSION -0.5
diff -urN dmd--0.7/support.scm dmd--0.5/support.scm
--- dmd--0.7/support.scm	2003-02-17 18:16:12.000000000 +0100
+++ dmd--0.5/support.scm	2003-05-01 22:17:54.000000000 +0200
@@ -25,7 +25,14 @@
 	 ((_ ARG ...)
 	  (RESULT ...)))))))
 
-;; An obvious alias.
+;; For parts of the code specific to dmd.
+(if (string=? program-name "dmd")
+    (define-syntax-rule (begin-dmd EXPR ...)
+      (begin EXPR ...))
+    (define-syntax-rule (begin-dmd EXPR ...)
+      (begin #f)))
+
+;; An obvious alias.  We currently do not use this, though.
 (define call/cc call-with-current-continuation)
 
 ;; Implement `call-with-escape-continuation' with `catch' and `throw'.
@@ -35,17 +42,25 @@
 	 (escape (lambda (value)
 		   (throw catch-sym value))))
     (catch catch-sym
-	   (lambda ()
-	     (proc escape))
-	   (lambda (sym value)
-	     value))))
+      (lambda ()
+	(proc escape))
+      (lambda (sym value)
+	value))))
 
 ;; Report the caught error.
-;; FIXME: There are better ways to do this.
+;; FIXME: Needs some more work.
 (define (caught-error key args)
-  (display key)
-  (write args)
-  (newline))
+  (case key
+    ((wrong-number-of-args)
+     (apply (lambda (subr fmt fmt-args data)
+	      (format #t "In ~a: " subr)
+	      (apply format #t fmt fmt-args)
+	      (newline))
+	    args))
+    (else
+     (display key)
+     (write args)
+     (newline))))
 
 ;; Assert that expression EXPR does not evaluate to `#f'.
 (define-syntax-rule (assert EXPR)
@@ -54,6 +69,43 @@
 	 (local-output "Assertion ~a failed." 'EXPR)
 	 (throw 'assertion-failed))))
 
+;; Recursive procedures.
+(define-syntax-rule (label NAME PROC)
+  (lambda args
+    (letrec ((NAME PROC))
+      (apply NAME args))))
+
+;; Lambda with optional arguments, call this like:
+;; (opt-lambda (req1 req2)
+;;             ((opt1 default1) (opt2 default2))
+;;    body)
+(define-macro (opt-lambda required optional . body)
+  `(label opt-lambda-rec
+     (lambda args
+       (assert (>= (length args) (length ',required)))
+       (if (< (length args) (+ (length ',required)
+                               (length ',optional)))
+           (apply opt-lambda-rec
+                  (append args
+                          (map cadr
+                               (list-tail ',optional
+                                          (- (length args)
+                                             (length ',optional))))))
+         (apply (lambda ,(append required
+                                 (map car optional))
+                  ,@body)
+                args)))))
+
+
+;; Check whether a list of NUM-ARGS arguments can successfully be
+;; applied to PROC.
+(define (can-apply? proc num-args)
+  (apply-to-args (procedure-property proc 'arity)
+		 (lambda (required optional takes-rest)
+		   (and (>= num-args required)
+			(or takes-rest
+			    (<= num-args (+ required optional)))))))
+
 ;; Put the data from TABLE into a new hash-table of size SIZE.  Use
 ;; `eq?' when inserting.  This will be dropped as soon as stable Guile
 ;; supports resizable hash tables (it's in the Guile CVS already).
@@ -64,13 +116,14 @@
 	     (make-hash-table size)
 	     table))
 
-;; Ignore a system error in case it occurs.
-(define-syntax-rule (without-system-error EXPR ...)
+;; Evaluate `EXPR ...' until a system error occurs, then skip the
+;; remaining code.
+(define-syntax-rule (catch-system-error EXPR ...)
   (catch 'system-error
-	 (lambda ()
-	   EXPR ...)
-	 (lambda (key . args)
-	   #f)))
+    (lambda ()
+      EXPR ...)
+    (lambda (key . args)
+      #f)))
 
 
 
@@ -80,63 +133,13 @@
   (lambda (str)
     str))
 
-(define real-output-port (current-output-port))
-(define void-output-port (%make-void-port "w"))
-(define log-output-port #f)
-
-(define (be-silent)
-  (set-current-output-port void-output-port))
-
-(define (be-verbose)
-  (set-current-output-port real-output-port))
-
-(define extra-output-sender #f)
-(define extra-output-sender-enabled #t)
-;; FIXME: That may be ``good enough'', but should be fixed anyway.
-(define terminating-string "!§&§&§&§&!") ;; Unlikely to appear in output.
-
-(define (open-extra-sender file)
-  (without-system-error
-   (set! extra-output-sender (make <sender> file))))
-
-(define (close-extra-sender)
-  (without-system-error
-   (send-data extra-output-sender terminating-string)
-   (set! extra-output-sender #f)))
-
-(define (start-logging file)
-  (set! log-output-port (open-file file "wl"))) ;; Line-buffered port.
-
-(define (stop-logging)
-  (set! log-output-port #f))
-
-(define-syntax-rule (without-extra-output EXPR ...)
-  (catch #t
-	 (lambda ()
-	   (set! extra-output-sender-enabled #f)
-	   EXPR ...
-	   (set! extra-output-sender-enabled #t))
-	 (lambda (key . args)
-	   (set! extra-output-sender-enabled #f)
-	   (apply throw (cons key args)))))
-
 ;; Display some text and a newline.  Need to use lambda.  *sigh*
 (define local-output
   (lambda (format-string . args)
-    (let ((text (apply format #f (l10n format-string) args)))
-      (write-line text)
-      (and log-output-port
-	   (write-line (string-append (strftime "%Y-%m-%d %H:%M:%S "
-						(localtime (current-time)))
-				      text)
-		       log-output-port))
-      (and extra-output-sender
-	   extra-output-sender-enabled
-	   (without-system-error
-	    (send-data extra-output-sender text))))))
+    (write-line (apply format #f (l10n format-string) args))))
 
 (define (display-version)
-  (local-output "~a -- ~a" banner copyright))
+  (local-output "~a ~a -- ~a" program-name Version copyright))
 
 
 
@@ -147,13 +150,13 @@
 (define default-logfile
   (if (zero? (getuid))
       (string-append Prefix-dir "/var/log/dmd.log")
-      (string-append user-homedir "/.dmd.log")))
+    (string-append user-homedir "/.dmd.log")))
 
 ;; Configuration file.
 (define default-config-file
   (if (zero? (getuid))
       (string-append Prefix-dir "/etc/dmdconf.scm")
-      (string-append user-homedir "/.dmdconf.scm")))
+    (string-append user-homedir "/.dmdconf.scm")))
 
 ;; The directory where the socket resides.
 (define default-socket-dir
@@ -173,23 +176,23 @@
 (define default-persistency-state-file
   (if (zero? (getuid))
       (string-append Prefix-dir "/var/lib/misc/dmd-state")
-      (string-append user-homedir "/.dmd-state")))
+    (string-append user-homedir "/.dmd-state")))
 
 ;; Check if the directory DIR exists and create it if it is the
-;; default directory, but does not exist.  If INSECURE? is `#f', also
+;; default directory, but does not exist.  If INSECURE is false, also
 ;; checks for the permissions of the directory.
-(define (verify-dir dir insecure?)
+(define (verify-dir dir insecure)
   (and (string=? dir default-socket-dir)
        ;; If it exists already, this is fine, thus ignore errors.
-       (without-system-error
+       (catch-system-error
 	(mkdir default-socket-dir #o700)))
 
   ;; Check for permissions.
-  (and (not insecure?)
-       (let ((dir-stat (stat dir)))
-	 (and (not (and (= (stat:uid dir-stat) (getuid))
-			(= (stat:perms dir-stat) #o700)))
-	      (begin
-		(local-output "Socket directory setup is insecure.")
-		(quit 1))))))
+  (or insecure
+      (let ((dir-stat (stat dir)))
+	(and (not (and (= (stat:uid dir-stat) (getuid))
+		       (= (stat:perms dir-stat) #o700)))
+	     (begin
+	       (local-output "Socket directory setup is insecure.")
+	       (quit 1))))))
 
diff -urN dmd--0.7/utils/Makefile.in dmd--0.5/utils/Makefile.in
--- dmd--0.7/utils/Makefile.in	2003-02-20 17:13:27.000000000 +0100
+++ dmd--0.5/utils/Makefile.in	2003-04-08 17:09:11.000000000 +0200
@@ -68,6 +68,12 @@
 AMTAR = @AMTAR@
 AWK = @AWK@
 DEPDIR = @DEPDIR@
+GUILE = @GUILE@
+GUILE_CFLAGS = @GUILE_CFLAGS@
+GUILE_CONFIG = @GUILE_CONFIG@
+GUILE_LDFLAGS = @GUILE_LDFLAGS@
+GUILE_SITE = @GUILE_SITE@
+GUILE_TOOLS = @GUILE_TOOLS@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 PACKAGE = @PACKAGE@
 STRIP = @STRIP@
diff -urN dmd--0.7/version.texi dmd--0.5/version.texi
--- dmd--0.7/version.texi	2003-02-20 17:10:57.000000000 +0100
+++ dmd--0.5/version.texi	2003-05-01 22:40:31.000000000 +0200
@@ -1,4 +1,4 @@
-@set UPDATED 17 February 2003
-@set UPDATED-MONTH February 2003
-@set EDITION -0.7
-@set VERSION -0.7
+@set UPDATED 16 April 2003
+@set UPDATED-MONTH April 2003
+@set EDITION -0.5
+@set VERSION -0.5

