]> git.tue.mpg.de Git - dss.git/commitdiff
Centralize meta information about dss.
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 7 May 2024 22:04:05 +0000 (00:04 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Tue, 2 Jul 2024 16:52:03 +0000 (18:52 +0200)
This defines a couple of package related variables in Makefile,
renames dss.suite -> dss.suite.m4 and index.html.in -> index.html.m4,
and tweaks the recipes to generate dss.suite and index.html.in from
the m4 files, referring to these variables. The contents of the
README file are moved into Makefile so that the three paragraphs can
be printed with make README.

.gitignore
Makefile
README
dss.suite [deleted file]
dss.suite.m4 [new file with mode: 0644]
index.html.in [deleted file]
index.html.m4 [new file with mode: 0644]

index fc6a8bb8dea359847f299ddb6fcb9afa9e750c13..aedd74e2272067da39fda26661646bb0f6832160 100644 (file)
@@ -5,6 +5,7 @@ version.c
 *.swp
 dss.lsg.*
 dss
+dss.suite
 dss.1.gz
 dss.1.html
 index.html
index eaf3e540f4c08885de9f82c456f11bc1121a6ea6..46b9c8cf8d00e98f648b4d813fb2fe8c02c9202a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,22 +1,74 @@
 # SPDX-License-Identifier: GPL-2.0
+
+PACKAGE := dss
+SLOGAN := the dyadic snapshot scheduler
+define DESCRIPTION1 :=
+       $(PACKAGE) maintains hardlink-based snapshots of a given directory on a
+       remote or local host using rsync's link-dest feature. The snapshots
+       are organized so that any snapshot can directly be deployed as an
+       (emergency) replacement for the primary system.
+endef
+define DESCRIPTION2 :=
+       $(PACKAGE) is admin friendly: It is easy to configure and needs little
+       attention after the initial setup. In particular, no full, incremental
+       or differential backups need to be configured, and there is no database
+       to maintain. $(PACKAGE) is also user-friendly: Assuming the snapshot server
+       allows read-only user access over the network, users can restore
+       accidentically removed files without admin intervention, using their
+       favorite file browser to copy files from the snapshot directory back
+       to the primary system.
+endef
+define DESCRIPTION3 :=
+       $(PACKAGE) keeps track of the age and the state of existing snapshots and
+       triggers snapshot creation and removal according to the configuration
+       settings. It tries to maintain a scheme where many recent snapshots
+       and few old snapshots exist, for example 16 snapshots newer than a
+       week, 8 snapshots between one and two weeks old, 4 snapshots between
+       two and three weeks old, and so on.
+endef
+AUTHOR := Andre Noll
+EMAIL := maan@tuebingen.mpg.de
+URL := https://people.tuebingen.mpg.de/maan/$(PACKAGE)/
+CLONE_URL := https://git.tuebingen.mpg.de/$(PACKAGE)
+GITWEB_URL := https://git.tuebingen.mpg.de/$(PACKAGE).git
+PACKAGE_HOMEPAGE := https://people.tuebingen.mpg.de/maan/$(PACKAGE)/
+HOME_URL := https://people.tuebingen.mpg.de/maan/
+LICENSE := GPL-2.0
+LICENSE_URL := https://www.gnu.org/licenses/
+
 PREFIX ?= /usr/local
 INSTALL ?= install
 INSTALL_PROGRAM ?= $(INSTALL)
 INSTALL_DATA ?= $(INSTALL) -m 644
 MKDIR_P := mkdir -p
-VERSION := $(shell ./version-gen.sh dss version.c)
+VERSION := $(shell ./version-gen.sh $(PACKAGE) version.c)
 RM := rm -f
 LSG := lopsubgen
 GROFF := groff -m man -Thtml -P -l -P -r
 GZIP := gzip -cfn9
-
-units := dss str file exec sig daemon df tv snap ipc dss.lsg version
+units := $(PACKAGE) $(PACKAGE).lsg str file exec sig daemon df tv snap ipc version
+M4 := m4 \
+       -D "AUTHOR=$(AUTHOR)" \
+       -D "PACKAGE=$(PACKAGE)" \
+       -D "SLOGAN=$(SLOGAN)" \
+       -D "EMAIL=$(EMAIL)" \
+       -D "URL=$(URL)" \
+       -D "CLONE_URL=$(CLONE_URL)" \
+       -D "GITWEB_URL=$(GITWEB_URL)" \
+       -D "HOME_URL=$(HOME_URL)" \
+       -D "PACKAGE_HOMEPAGE=$(PACKAGE_HOMEPAGE)" \
+       -D "LICENSE=$(LICENSE)" \
+       -D "LICENSE_URL=$(LICENSE_URL)" \
+       -D "DESCRIPTION1=$(DESCRIPTION1)" \
+       -D "DESCRIPTION2=$(DESCRIPTION2)" \
+       -D "DESCRIPTION3=$(DESCRIPTION3)"
 objs := $(addsuffix .o, $(units))
 deps := $(addsuffix .d, $(units))
+all := $(PACKAGE) $(PACKAGE).1.gz
 
-all: dss dss.1.gz
-man: dss.1.gz
-$(objs): dss.lsg.h Makefile
+all: $(all)
+man: $(PACKAGE).1.gz
+$(objs): $(PACKAGE).lsg.h Makefile
 -include $(deps)
 
 DSS_CPPFLAGS += -Wunused-macros
@@ -43,15 +95,20 @@ else
 endif
 version.c:
        $(call SAY, VG $@)
-       ./version-gen.sh dss version.c > /dev/null
-dss: $(objs)
+       ./version-gen.sh $(PACKAGE) version.c > /dev/null
+$(PACKAGE): $(objs)
        $(call SAY, LD $@)
        $(CC) -o $@ $(objs) $(LDFLAGS) -llopsub
 %.o: %.c
        $(call SAY, CC $<)
        $(CC) -c -o $@ $(DSS_CPPFLAGS) $(CPPFLAGS) $(DSS_CFLAGS) $(CFLAGS) \
                -MMD -MF $(*F).d -MT $@ $<
-.PRECIOUS: %.lsg.c %.lsg.h %.1.gz
+
+.PHONY: all clean install README
+.PRECIOUS: %.lsg.c %.lsg.h %.suite %.1
+$(PACKAGE).suite: $(PACKAGE).suite.m4 Makefile
+       $(call SAY, M4 $<)
+       $(M4) $< > $@
 %.lsg.h: %.suite
        $(call SAY, LSGH $<)
        $(LSG) --gen-h=$@ < $<
@@ -69,7 +126,8 @@ dss: $(objs)
        $(GROFF) $< | sed -e '1,/^<body>/d; /^<\/body>/,$$d' > $@
 clean:
        $(call SAY, CLEAN)
-       $(RM) *.[od] dss dss.1.* *.html dss.lsg.[ch] version.c
+       $(RM) *.[od] $(all) *.html $(PACKAGE).1 $(PACKAGE).suite \
+               $(PACKAGE).lsg.[ch] version.c
 
 ifneq ($(findstring strip, $(MAKECMDGOALS)),)
        strip_option := -s
@@ -78,12 +136,39 @@ bindir := $(DESTDIR)$(PREFIX)/bin
 mandir := $(DESTDIR)$(PREFIX)/share/man/man1
 install install-strip: all
        $(MKDIR_P) $(bindir) $(mandir)
-       $(INSTALL_PROGRAM) $(strip_option) dss $(bindir)
-       $(INSTALL_DATA) dss.1.gz $(mandir)
+       $(INSTALL_PROGRAM) $(strip_option) $(PACKAGE) $(bindir)
+       $(INSTALL_DATA) $(PACKAGE).1.gz $(mandir)
+
+define README :=
+$(PACKAGE) - $(SLOGAN)
+
+$(DESCRIPTION1)
+
+$(DESCRIPTION2)
+
+$(DESCRIPTION3)
+
+Resources
+~~~~~~~~~
+web page: $(PACKAGE_HOMEPAGE)
+git clone URL: $(CLONE_URL)
+gitweb: $(GITWEB_URL)
+author home page: $(HOME_URL)
+report bugs to: $(AUTHOR) <$(EMAIL)>
+endef
+
+README:
+       @printf '%s\n' "$(README)"
 
-index.html: dss.1.html index.html.in INSTALL README NEWS
+index.html.in: index.html.m4
+       $(call SAY, M4 $<)
+       $(M4) $< > $@
+index.html: dss.1.html index.html.in INSTALL NEWS
+       $(call SAY, MD $@)
        sed -e '/@README@/,$$d' index.html.in > $@
-       markdown README >> $@
+       printf '<p> %s </p>\n' "$(DESCRIPTION1)" >> $@
+       printf '<p> %s </p>\n' "$(DESCRIPTION2)" >> $@
+       printf '<p> %s </p>\n' "$(DESCRIPTION3)" >> $@
        sed -e '1,/@README@/d' -e '/@NEWS@/,$$d' index.html.in >> $@
        markdown NEWS >> $@
        sed -e '1,/@NEWS@/d' -e '/@INSTALL@/,$$d' index.html.in >> $@
diff --git a/README b/README
index 052ea8d75c27bdbf1aaeb7a33d1a6b12e7acc2c4..52a1fd78fce783b7f09e22a32484f74fbf622f12 100644 (file)
--- a/README
+++ b/README
@@ -1,20 +1 @@
-dss maintains hardlink-based snapshots of a given directory on a
-remote or local host using rsync's link-dest feature. The snapshots
-are organized so that any snapshot can directly be deployed as an
-(emergency) replacement for the primary system.
-
-dss is admin friendly: It is easy to configure and needs little
-attention after the initial setup. In particular, no full, incremental
-or differential backups need to be configured, and there is no database
-to maintain. dss is also user-friendly: Assuming the snapshot server
-allows read-only user access over the network, users can restore
-accidentically removed files without admin intervention, using their
-favorite file browser to copy files from the snapshot directory back
-to the primary system.
-
-dss keeps track of the age and the state of existing snapshots and
-triggers snapshot creation and removal according to the configuration
-settings. It tries to maintain a scheme where many recent snapshots
-and few old snapshots exist, for example 16 snapshots newer than a
-week, 8 snapshots between one and two weeks old, 4 snapshots between
-two and three weeks old, and so on.
+Run "make README".
diff --git a/dss.suite b/dss.suite
deleted file mode 100644 (file)
index f9cf8af..0000000
--- a/dss.suite
+++ /dev/null
@@ -1,564 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-[suite dss]
-caption = Subcommands
-
-[supercommand dss]
-       [description]
-               dss creates hardlink-based snapshots of a given directory on a remote
-               or local host using rsync's link-dest feature.
-       [/description]
-       purpose = the dyadic snapshot scheduler
-       synopsis = [global-options...] [--] [<subcommand> [subcommand-options...]]
-
-       [option general-options-section]
-               summary = General options
-               flag ignored
-       [option help]
-               summary = print help and exit
-               short_opt = h
-       [option detailed-help]
-               summary = print help, including all details, and exit
-       [option version]
-               summary = print version and exit
-               short_opt = V
-       [option config-file]
-               short_opt = c
-               summary = use alternative config file (default: ~/.dssrc)
-               typestr = path
-               arg_info = required_arg
-               arg_type = string
-               [help]
-                       Options may be given at the command line or in the configuration
-                       file. As usual, if an option is given both at the command line and
-                       in the configuration file, the command line option takes precedence.
-
-                       However, there is one exception to this rule: The run subcommand
-                       re-reads the configuration file when it receives the HUP signal. In
-                       this case the options in the config file override any options that
-                       were previously given at the command line. This allows changing the
-                       configuration of a running dss process by sending SIGHUP.
-               [/help]
-       [option loglevel]
-               short_opt = l
-               summary = set loglevel (0-6)
-               typestr = level
-               arg_info = required_arg
-               arg_type = uint32
-               default_val = 4
-               [help]
-                       Lower values mean more verbose logging.
-               [/help]
-       [option dry-run]
-               short_opt = n
-               summary = only print what would be done
-               [help]
-                       This flag does not make sense for all subcommands. The run subcommand
-                       refuses to start if this option was given while the ls subcommand
-                       silently ignores the flag.
-               [/help]
-       [option source-dir]
-               summary = the remote directory to snapshot
-               typestr = dirname
-               arg_info = required_arg
-               arg_type = string
-               flag multiple
-               [help]
-                       The directory on the remote host from which snapshots are taken.
-                       Of course, the user specified as --remote-user must have read access
-                       to this directory.
-
-                       This option is mandatory for the create and run subcommands: It may
-                       be given multiple times to specify more than one source directory.
-                       However, all source directories must reside on the same server.
-               [/help]
-       [option dest-dir]
-               summary = where snapshots are stored
-               typestr = dirname
-               arg_info = required_arg
-               arg_type = string
-               [help]
-                       The destination directory on the local host where snapshots will be
-                       written. This must be writable by the user who runs dss.
-
-                       This option is mandatory for all subcommands except kill.
-                       Unlike --source-dir, this option may only be given once.
-               [/help]
-       [option mountpoint]
-               summary = abort if destination directory is not a mountpoint
-               [help]
-                       This option checks whether a file system is mounted on the directory
-                       specified as the argument to --dest-dir. Operation proceeds only
-                       if this is the case. Otherwise dss exits unsuccessfully without
-                       performing any action. Use this option to prevent snapshot creation
-                       if the snapshot file system is not mounted.
-
-                       This option is silently ignored for subcommands which do not depend
-                       on the destination directory.
-               [/help]
-       [option Rsync-options]
-               summary = Controlling how rsync is run
-               flag ignored
-               [help]
-                       These options are only relevant to the run and the create subcommands.
-               [/help]
-       [option remote-host]
-               short_opt = H
-               summary = host to take snapshots from
-               typestr = hostname
-               arg_info = required_arg
-               arg_type = string
-               default_val = localhost
-               [help]
-                       If this option is given and its value differs from the local
-                       host, then rsync uses ssh. Make sure there is no password
-                       needed for the ssh connection. To achieve that, use public key
-                       authentication for ssh and, if needed, set the remote user name
-                       by using the --remote-user option.
-               [/help]
-       [option remote-user]
-               short_opt = U
-               summary = Remote user name (default: current user)
-               arg_info = required_arg
-               typestr = username
-               arg_type = string
-               [help]
-                       Set this if the user that runs dss is different from the user on the
-                       remote host.
-               [/help]
-       [option checksum]
-               summary = run rsync with --checksum occasionally
-               typestr = permille
-               arg_info = required_arg
-               arg_type = uint32
-               default_val = 0
-               [help]
-                       If a file on the backup becomes corrupt in a way that file size
-                       and modification time still match the original file, rsync will not
-                       consider the file for transfer ("quick check"). Hence the corruption
-                       stays on the backup until the file is modified on the source.
-                       The --checksum option of rsync disables the quick check and compares
-                       the contents of each file, fixing such corruptions. Since computing
-                       the checksums adds a significant slowdown due to a lot of disk I/O,
-                       the option is not enabled by default.
-
-                       The argument to the --checksum option of dss is a number between 0
-                       and 1000, inclusively, which determines the probability of adding
-                       --checksum to the rsync options each time a snapshot is created. The
-                       default value zero means to never add the option. The value 100 will
-                       create every tenth snapshot (on average) using checksums, and the
-                       value 1000 will always pass --checksum to rsync.
-               [/help]
-       [option rsync-option]
-               short_opt = O
-               summary = further rsync options
-               typestr = option
-               arg_info = required_arg
-               arg_type = string
-               flag multiple
-               [help]
-                       This option may be given multiple times. The given argument is
-                       passed verbatim to the rsync command. Note that in order to use
-                       rsync options that require an argument, you have to specify the
-                       option and its argument as separate --rsync-options, like this:
-
-                               --rsync-option --exclude --rsync-option /proc
-               [/help]
-       [option intervals]
-               summary = Fine tuning the number of snapshots per time unit
-               flag ignored
-               [help]
-                       Snapshot aging is implemented in terms of intervals. There are two
-                       command line options related to intervals: the duration u of a unit
-                       interval and the number of unit intervals, denoted n below.
-
-                       dss removes snapshots older than n times u and tries to keep 2^(n -
-                       k - 1) snapshots in interval k, where the interval number k counts
-                       from zero to n - 1, with zero being the most recent unit interval.
-
-                       Hence the oldest snapshot will at most be u * n days old (4 days *
-                       5 intervals = 20 days, if default values are used). Moreover, there
-                       are at most 2^n - 1 snapshots in total (2^5 - 1 = 31 by default). Note
-                       that for this to work out your system must be fast enough to create at
-                       least 2^(n - 1) snapshots per unit interval (16 snapshots in 4 days =
-                       one snapshot in 6 hours), because this is the number of snapshots in
-                       interval zero.
-               [/help]
-       [option unit-interval]
-               short_opt = u
-               summary = the duration of a unit interval
-               typestr = days
-               arg_info = required_arg
-               arg_type = uint32
-               default_val = 4
-               [help]
-                       Increasing this number instructs dss to create fewer snapshots per
-                       time unit while the number of snapshots to keep stays the same.
-               [/help]
-       [option num-intervals]
-               short_opt = n
-               summary = the number of unit intervals
-               typestr = num
-               arg_info = required_arg
-               arg_type = uint32
-               default_val = 5
-               [help]
-                       Increasing this number by one doubles the total number of
-                       snapshots.
-               [/help]
-       [option hooks]
-               summary = Commands to be run on certain events
-               flag ignored
-               [help]
-                       All hooks default to "true". That is, the true(1) utility (which
-                       always returns with exit code zero) is executed if the hook command
-                       is not specified.
-               [/help]
-       [option pre-create-hook]
-               short_opt = r
-               summary = executed before a snapshot is created
-               typestr = command
-               arg_info = required_arg
-               arg_type = string
-               default_val = true
-               [help]
-                       This command is executed before dss runs rsync to create a new
-                       snapshot. If the command returns with a non-zero exit status, no
-                       snapshot will be created and the operation is retried later.
-
-                       For example, the command could execute a script that checks whether
-                       all snapshot-related file systems are mounted.
-
-                       Another possible application of the pre-create hook is to return
-                       non-zero during office hours in order to not slow down the file
-                       systems by taking snapshots.
-               [/help]
-       [option post-create-hook]
-               summary = executed after a snapshot has been created
-               typestr = command
-               arg_info = required_arg
-               arg_type = string
-               default_val = true
-               [help]
-                       This is only executed if a snapshot has successfully been created. The
-                       full path of the newly created snapshot is passed to the hook as the
-                       first argument. The exit code of this hook is ignored.
-
-                       For instance this hook could count the number of files per user
-                       and/or compute disk usage patterns to be stored in a database for
-                       further analysis.
-               [/help]
-       [option pre-remove-hook]
-               summary = executed before a snapshot is removed
-               typestr = command
-               arg_info = required_arg
-               arg_type = string
-               default_val = true
-               [help]
-                       The full path to the snapshot which is about to be removed is passed
-                       to the command as the first argument. If the command returns with
-                       a non-zero exit status, the snapshot is not going to be removed and
-                       the operation is retried later.
-
-                       For example, one could execute a script that checks whether the
-                       snapshot to be deleted is currently used by another process, e.g. by
-                       a tape-based backup system that runs concurrently to dss.
-
-                       Another possible application of this is to record disk-usage
-                       patterns before and after snapshot removal.
-               [/help]
-       [option post-remove-hook]
-               summary = executed after snapshot removal
-               typestr = command
-               arg_info = required_arg
-               arg_type = string
-               default_val = true
-               [help]
-                       As for the pre-remove hook, the full path of the removed snapshot is
-                       passed to the hook as the first argument. The exit code of this hook
-                       is ignored.
-               [/help]
-       [option exit-hook]
-               summary = executed before the run command exits
-               typestr = command
-               arg_info = required_arg
-               arg_type = string
-               default_val = true
-               [help]
-                       This hook is only relevant to the run subcommand. It is executed just
-                       before dss terminates. The reason for termination is passed as the
-                       first argument.
-
-                       One possible application for this hook is to send email to the system
-                       administrator to let her know that no more snapshots are going to
-                       be created.
-               [/help]
-
-       [option disk-space-monitoring]
-               summary = Disk space monitoring
-               flag ignored
-               [help]
-                       The options of this section control the aggressiveness of snapshot
-                       removal. That is, they define under which circumstances existing
-                       snapshots are removed. These options are only relevant to the run
-                       and the prune subcommands.
-               [/help]
-       [option min-free-mb]
-               short_opt = m
-               summary = minimal amount of free disk space
-               arg_info = required_arg
-               arg_type = uint32
-               typestr = megabytes
-               default_val = 100
-               [help]
-                       If disk space on the file system containing the destination
-                       directory gets low, the run subcommand suspends the currently
-                       running rsync process and starts to remove snapshots in order to
-                       free disk space. This option specifies the minimal amount of free
-                       disk space. If less than the given number of megabytes is available,
-                       snapshots are being deleted. See also the --min_free_percent and the
-                       min-free-percent-inodes options below.
-
-                       A value of zero deactivates this check.
-               [/help]
-       [option min-free-percent]
-               short_opt = p
-               summary = minimal percentage of free disk space
-               arg_info = required_arg
-               arg_type = uint32
-               typestr = percent
-               default_val = 2
-               [help]
-                       This is like --min-free-mb but the amount of free disk space
-                       is specified as a percentage. It is not recommended to set both
-                       --min-free-mb and --min-free-percent to zero as this will cause your
-                       file system to fill up quickly.
-               [/help]
-       [option min-free-percent-inodes]
-               short_opt = i
-               summary = minimal percent of free inodes
-               arg_info = required_arg
-               arg_type = uint32
-               typestr = percent
-               default_val = 0
-               [help]
-                       The minimum amount of free inodes on the file system containing the
-                       destination dir. If the percentage of free inodes drops below the
-                       given value, snapshot removal kicks in like in case of low disk space.
-
-                       The number of free inodes is determined from the f_ffree field of
-                       the statvfs structure. However, some file systems set this field to
-                       zero, indicating that the number of inodes is basically unlimited.
-                       Moreover it is not possible to reliably detect whether this is the
-                       case. Therefore this feature is disabled by default. It's safe to
-                       enable it for ext2/ext3/ext4 file systems on linux though.
-
-                       A value of zero (the default) deactivates this check.
-               [/help]
-       [option keep-redundant]
-               short_opt = k
-               summary = prune by disk space only
-               [help]
-                       By default, redundant and outdated snapshots are removed automatically
-                       to keep the number of snapshots in harmony with the configured
-                       policy. If this flag is given, dss removes such snapshots only if
-                       disk space or number of free inodes becomes low.
-               [/help]
-       [option min-complete]
-               summary = minimal number of complete snapshots to keep
-               arg_info = optional_arg
-               arg_type = uint32
-               typestr = num
-               default_val = 1
-               [help]
-                       This option is only relevant if snapshots must be deleted because
-                       disk space gets low.
-
-                       dss refuses to remove old snapshots if there are fewer complete
-                       snapshots left than the given number. The default value of one
-                       guarantees that at least one complete snapshot is available at
-                       all times.
-
-                       If only <num> complete snapshots are left, and there is not enough
-                       disk space available for another snapshot, the program terminates
-                       with a "No space left on device" error.
-               [/help]
-
-[introduction]
-       dss supports the subcommands described below. If no subcommand is
-       given, the list of available subcommands is shown and the program
-       terminates successfully without performing any further action.
-[/introduction]
-
-[subcommand run]
-       purpose = start creating and pruning snapshots
-       [description]
-               This is the main mode of operation. Snapshots are created in an endless
-               loop as needed and pruned automatically. The loop only terminates on
-               fatal errors or if a terminating signal was received. See also the
-               --exit-hook option.
-       [/description]
-       [option daemon]
-               short_opt = d
-               summary = run as background daemon
-               [help]
-                       If this option is given, the dss command detaches from the console
-                       and continues to run in the background. It is not possible to let
-                       a daemonized process re-attach to the console by editing the config
-                       file and sending SIGHUP. However, log output may be redirected to a
-                       different file in this way.
-
-                       See --logfile.
-               [/help]
-       [option logfile]
-               short_opt = l
-               summary = where to write log output
-               arg_info = required_arg
-               arg_type = string
-               typestr = path
-               default_val = /dev/null
-               [help]
-                       This option is only honored if --daemon is given, in which case
-                       log messages go to the given file. Otherwise the option is silently
-                       ignored and log output is written to stderr.
-               [/help]
-       [option max-rsync-errors]
-               summary = terminate after this many rsync failures
-               typestr = count
-               arg_info = required_arg
-               arg_type = uint32
-               default_val = 10
-               [help]
-                       If the rsync process exits with a fatal error, dss restarts the command
-                       in the hope that the problem is transient and subsequent rsync runs
-                       succeed. After the given number of consecutive rsync error exits,
-                       however, dss gives up, executes the exit hook and terminates. Set
-                       this to zero if dss should exit immediately on the first rsync error.
-
-                       The only non-fatal error is when rsync exits with code 24. This
-                       indicates a partial transfer due to vanished source files and happens
-                       frequently when snapshotting a directory which is concurrently being
-                       modified.
-               [/help]
-[subcommand create]
-       purpose = execute rsync once to create a new snapshot
-       [description]
-               This command does not check the amount free disk space. The pre-create
-               and post-create hooks are honored, however.
-
-               Specify --dry-run to see the rsync command which is executed to create
-               snapshots.
-       [/description]
-[subcommand prune]
-       purpose = remove snapshots
-       [description]
-               A snapshot is said to be (a) outdated if its interval number is greater
-               or equal than the specified number of unit intervals, (b) redundant if
-               the interval it belongs to contains more than the configured number of
-               snapshots, and (c) orphaned if it is incomplete and not being created
-               or deleted. All other snapshots are called regular.
-
-               Unless --dry-run is given, which just prints the snapshot that would be
-               removed, this subcommand gets rid of non-regular snapshots.  At most
-               one snapshot is removed per invocation. If no such snapshot exists
-               and disk space is low, the subcommand also removes regular snapshots,
-               always picking the oldest one.
-
-               The subcommand fails if there is another dss "run" process.
-       [/description]
-       [option disk-space]
-               summary = act as if free disk space was high/low
-               arg_info = required_arg
-               arg_type = string
-               typestr = mode
-               values = {
-                       FDS_CHECK = "check",
-                       FDS_HIGH = "high",
-                       FDS_LOW = "low"
-               }
-               default_val = check
-               [help]
-                       By default, free disk space is checked and even regular snapshots
-                       become candidates for removal if disk space is low. This option
-                       overrides the result of the check.
-               [/help]
-[subcommand ls]
-       purpose = print the list of all snapshots
-       [description]
-               The list contains all existing snapshots, no matter of their state.
-               Incomplete snapshots and snapshots being deleted will also be listed.
-       [/description]
-[subcommand kill]
-       purpose = send a signal to a running dss process
-       [description]
-               This sends a signal to the dss process that corresponds to the given
-               config file. If --dry-run is given, the PID of the dss process is
-               written to stdout, but no signal is sent.
-       [/description]
-       [option signal]
-               short_opt = s
-               summary = send the given signal rather than SIGTERM
-               typestr = signal
-               arg_info = required_arg
-               arg_type = string
-               default_val = SIGTERM
-               [help]
-                       Like for kill(1), alternate signals may be specified in three ways: as
-                       a signal number (e.g., 9), the signal name (e.g., KILL), or the signal
-                       name prefixed with "SIG" (e.g., SIGKILL). In the latter two forms,
-                       the signal name and the prefix are case insensitive, so "sigkill"
-                       works as well.
-
-                       Sending SIGHUP causes the running dss process to reload its config file.
-               [/help]
-       [option wait]
-               short_opt = w
-               summary = wait until the signalled process has terminated
-               [help]
-                       This option is handy for system shutdown scripts which would like
-                       to terminate the dss daemon process.
-
-                       Without --wait the dss process which executes the kill subcommand
-                       exits right after the kill(2) system call returns. At this point the
-                       signalled process might still be alive (even if SIGKILL was sent).
-                       If --wait is given, the process waits until the signalled process
-                       has terminated or the timeout expires.
-
-                       If --wait is not given, the kill subcommand exits successfully if
-                       and only if the signal was sent (i.e., if there exists another dss
-                       process to receive the signal). With --wait it exits successfully
-                       if, additionally, the signalled process has terminated before the
-                       timeout expires.
-
-                       It makes only sense to use the option for signals which terminate dss.
-               [/help]
-[subcommand configtest]
-       purpose = run a configuration file syntax test
-       [description]
-               This command checks the command line options and the configuration
-               file for syntactic correctness. It either reports "Syntax Ok" and
-               exits successfully or prints information about the first syntax error
-               detected and terminates with exit code 1.
-       [/description]
-
-[section copyright]
-       Written by Andre Noll
-       .br
-       Copyright (C) 2008 - present Andre Noll
-       .br
-       License: GNU GPL version 2
-       .br
-       This is free software: you are free to change and redistribute it.
-       .br
-       There is NO WARRANTY, to the extent permitted by law.
-       .br
-       Report bugs to
-       .MT <maan@tuebingen.mpg.de>
-       Andre Noll
-       .ME
-[/section]
-
-[section see also]
-       .BR ssh (1) ,
-       .BR rsync (1)
-[/section]
diff --git a/dss.suite.m4 b/dss.suite.m4
new file mode 100644 (file)
index 0000000..227b0b5
--- /dev/null
@@ -0,0 +1,583 @@
+# SPDX-License-Identifier: GPL-2.0
+
+[suite dss]
+caption = Subcommands
+
+[supercommand dss]
+       [description]
+               DESCRIPTION1()
+
+               DESCRIPTION2()
+
+               DESCRIPTION3()
+       [/description]
+       purpose = SLOGAN()
+       synopsis = [global-options...] [--] [<subcommand> [subcommand-options...]]
+
+       [option general-options-section]
+               summary = General options
+               flag ignored
+       [option help]
+               summary = print help and exit
+               short_opt = h
+       [option detailed-help]
+               summary = print help, including all details, and exit
+       [option version]
+               summary = print version and exit
+               short_opt = V
+       [option config-file]
+               short_opt = c
+               summary = use alternative config file (default: ~/.dssrc)
+               typestr = path
+               arg_info = required_arg
+               arg_type = string
+               [help]
+                       Options may be given at the command line or in the configuration
+                       file. As usual, if an option is given both at the command line and
+                       in the configuration file, the command line option takes precedence.
+
+                       However, there is one exception to this rule: The run subcommand
+                       re-reads the configuration file when it receives the HUP signal. In
+                       this case the options in the config file override any options that
+                       were previously given at the command line. This allows changing the
+                       configuration of a running dss process by sending SIGHUP.
+               [/help]
+       [option loglevel]
+               short_opt = l
+               summary = set loglevel (0-6)
+               typestr = level
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 4
+               [help]
+                       Lower values mean more verbose logging.
+               [/help]
+       [option dry-run]
+               short_opt = n
+               summary = only print what would be done
+               [help]
+                       This flag does not make sense for all subcommands. The run subcommand
+                       refuses to start if this option was given while the ls subcommand
+                       silently ignores the flag.
+               [/help]
+       [option source-dir]
+               summary = the remote directory to snapshot
+               typestr = dirname
+               arg_info = required_arg
+               arg_type = string
+               flag multiple
+               [help]
+                       The directory on the remote host from which snapshots are taken.
+                       Of course, the user specified as --remote-user must have read access
+                       to this directory.
+
+                       This option is mandatory for the create and run subcommands: It may
+                       be given multiple times to specify more than one source directory.
+                       However, all source directories must reside on the same server.
+               [/help]
+       [option dest-dir]
+               summary = where snapshots are stored
+               typestr = dirname
+               arg_info = required_arg
+               arg_type = string
+               [help]
+                       The destination directory on the local host where snapshots will be
+                       written. This must be writable by the user who runs dss.
+
+                       This option is mandatory for all subcommands except kill.
+                       Unlike --source-dir, this option may only be given once.
+               [/help]
+       [option mountpoint]
+               summary = abort if destination directory is not a mountpoint
+               [help]
+                       This option checks whether a file system is mounted on the directory
+                       specified as the argument to --dest-dir. Operation proceeds only
+                       if this is the case. Otherwise dss exits unsuccessfully without
+                       performing any action. Use this option to prevent snapshot creation
+                       if the snapshot file system is not mounted.
+
+                       This option is silently ignored for subcommands which do not depend
+                       on the destination directory.
+               [/help]
+       [option Rsync-options]
+               summary = Controlling how rsync is run
+               flag ignored
+               [help]
+                       These options are only relevant to the run and the create subcommands.
+               [/help]
+       [option remote-host]
+               short_opt = H
+               summary = host to take snapshots from
+               typestr = hostname
+               arg_info = required_arg
+               arg_type = string
+               default_val = localhost
+               [help]
+                       If this option is given and its value differs from the local
+                       host, then rsync uses ssh. Make sure there is no password
+                       needed for the ssh connection. To achieve that, use public key
+                       authentication for ssh and, if needed, set the remote user name
+                       by using the --remote-user option.
+               [/help]
+       [option remote-user]
+               short_opt = U
+               summary = Remote user name (default: current user)
+               arg_info = required_arg
+               typestr = username
+               arg_type = string
+               [help]
+                       Set this if the user that runs dss is different from the user on the
+                       remote host.
+               [/help]
+       [option checksum]
+               summary = run rsync with --checksum occasionally
+               typestr = permille
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 0
+               [help]
+                       If a file on the backup becomes corrupt in a way that file size
+                       and modification time still match the original file, rsync will not
+                       consider the file for transfer ("quick check"). Hence the corruption
+                       stays on the backup until the file is modified on the source.
+                       The --checksum option of rsync disables the quick check and compares
+                       the contents of each file, fixing such corruptions. Since computing
+                       the checksums adds a significant slowdown due to a lot of disk I/O,
+                       the option is not enabled by default.
+
+                       The argument to the --checksum option of dss is a number between 0
+                       and 1000, inclusively, which determines the probability of adding
+                       --checksum to the rsync options each time a snapshot is created. The
+                       default value zero means to never add the option. The value 100 will
+                       create every tenth snapshot (on average) using checksums, and the
+                       value 1000 will always pass --checksum to rsync.
+               [/help]
+       [option rsync-option]
+               short_opt = O
+               summary = further rsync options
+               typestr = option
+               arg_info = required_arg
+               arg_type = string
+               flag multiple
+               [help]
+                       This option may be given multiple times. The given argument is
+                       passed verbatim to the rsync command. Note that in order to use
+                       rsync options that require an argument, you have to specify the
+                       option and its argument as separate --rsync-options, like this:
+
+                               --rsync-option --exclude --rsync-option /proc
+               [/help]
+       [option intervals]
+               summary = Fine tuning the number of snapshots per time unit
+               flag ignored
+               [help]
+                       Snapshot aging is implemented in terms of intervals. There are two
+                       command line options related to intervals: the duration u of a unit
+                       interval and the number of unit intervals, denoted n below.
+
+                       dss removes snapshots older than n times u and tries to keep 2^(n -
+                       k - 1) snapshots in interval k, where the interval number k counts
+                       from zero to n - 1, with zero being the most recent unit interval.
+
+                       Hence the oldest snapshot will at most be u * n days old (4 days *
+                       5 intervals = 20 days, if default values are used). Moreover, there
+                       are at most 2^n - 1 snapshots in total (2^5 - 1 = 31 by default). Note
+                       that for this to work out your system must be fast enough to create at
+                       least 2^(n - 1) snapshots per unit interval (16 snapshots in 4 days =
+                       one snapshot in 6 hours), because this is the number of snapshots in
+                       interval zero.
+               [/help]
+       [option unit-interval]
+               short_opt = u
+               summary = the duration of a unit interval
+               typestr = days
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 4
+               [help]
+                       Increasing this number instructs dss to create fewer snapshots per
+                       time unit while the number of snapshots to keep stays the same.
+               [/help]
+       [option num-intervals]
+               short_opt = n
+               summary = the number of unit intervals
+               typestr = num
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 5
+               [help]
+                       Increasing this number by one doubles the total number of
+                       snapshots.
+               [/help]
+       [option hooks]
+               summary = Commands to be run on certain events
+               flag ignored
+               [help]
+                       All hooks default to "true". That is, the true(1) utility (which
+                       always returns with exit code zero) is executed if the hook command
+                       is not specified.
+               [/help]
+       [option pre-create-hook]
+               short_opt = r
+               summary = executed before a snapshot is created
+               typestr = command
+               arg_info = required_arg
+               arg_type = string
+               default_val = true
+               [help]
+                       This command is executed before dss runs rsync to create a new
+                       snapshot. If the command returns with a non-zero exit status, no
+                       snapshot will be created and the operation is retried later.
+
+                       For example, the command could execute a script that checks whether
+                       all snapshot-related file systems are mounted.
+
+                       Another possible application of the pre-create hook is to return
+                       non-zero during office hours in order to not slow down the file
+                       systems by taking snapshots.
+               [/help]
+       [option post-create-hook]
+               summary = executed after a snapshot has been created
+               typestr = command
+               arg_info = required_arg
+               arg_type = string
+               default_val = true
+               [help]
+                       This is only executed if a snapshot has successfully been created. The
+                       full path of the newly created snapshot is passed to the hook as the
+                       first argument. The exit code of this hook is ignored.
+
+                       For instance this hook could count the number of files per user
+                       and/or compute disk usage patterns to be stored in a database for
+                       further analysis.
+               [/help]
+       [option pre-remove-hook]
+               summary = executed before a snapshot is removed
+               typestr = command
+               arg_info = required_arg
+               arg_type = string
+               default_val = true
+               [help]
+                       The full path to the snapshot which is about to be removed is passed
+                       to the command as the first argument. If the command returns with
+                       a non-zero exit status, the snapshot is not going to be removed and
+                       the operation is retried later.
+
+                       For example, one could execute a script that checks whether the
+                       snapshot to be deleted is currently used by another process, e.g. by
+                       a tape-based backup system that runs concurrently to dss.
+
+                       Another possible application of this is to record disk-usage
+                       patterns before and after snapshot removal.
+               [/help]
+       [option post-remove-hook]
+               summary = executed after snapshot removal
+               typestr = command
+               arg_info = required_arg
+               arg_type = string
+               default_val = true
+               [help]
+                       As for the pre-remove hook, the full path of the removed snapshot is
+                       passed to the hook as the first argument. The exit code of this hook
+                       is ignored.
+               [/help]
+       [option exit-hook]
+               summary = executed before the run command exits
+               typestr = command
+               arg_info = required_arg
+               arg_type = string
+               default_val = true
+               [help]
+                       This hook is only relevant to the run subcommand. It is executed just
+                       before dss terminates. The reason for termination is passed as the
+                       first argument.
+
+                       One possible application for this hook is to send email to the system
+                       administrator to let her know that no more snapshots are going to
+                       be created.
+               [/help]
+
+       [option disk-space-monitoring]
+               summary = Disk space monitoring
+               flag ignored
+               [help]
+                       The options of this section control the aggressiveness of snapshot
+                       removal. That is, they define under which circumstances existing
+                       snapshots are removed. These options are only relevant to the run
+                       and the prune subcommands.
+               [/help]
+       [option min-free-mb]
+               short_opt = m
+               summary = minimal amount of free disk space
+               arg_info = required_arg
+               arg_type = uint32
+               typestr = megabytes
+               default_val = 100
+               [help]
+                       If disk space on the file system containing the destination
+                       directory gets low, the run subcommand suspends the currently
+                       running rsync process and starts to remove snapshots in order to
+                       free disk space. This option specifies the minimal amount of free
+                       disk space. If less than the given number of megabytes is available,
+                       snapshots are being deleted. See also the --min_free_percent and the
+                       min-free-percent-inodes options below.
+
+                       A value of zero deactivates this check.
+               [/help]
+       [option min-free-percent]
+               short_opt = p
+               summary = minimal percentage of free disk space
+               arg_info = required_arg
+               arg_type = uint32
+               typestr = percent
+               default_val = 2
+               [help]
+                       This is like --min-free-mb but the amount of free disk space
+                       is specified as a percentage. It is not recommended to set both
+                       --min-free-mb and --min-free-percent to zero as this will cause your
+                       file system to fill up quickly.
+               [/help]
+       [option min-free-percent-inodes]
+               short_opt = i
+               summary = minimal percent of free inodes
+               arg_info = required_arg
+               arg_type = uint32
+               typestr = percent
+               default_val = 0
+               [help]
+                       The minimum amount of free inodes on the file system containing the
+                       destination dir. If the percentage of free inodes drops below the
+                       given value, snapshot removal kicks in like in case of low disk space.
+
+                       The number of free inodes is determined from the f_ffree field of
+                       the statvfs structure. However, some file systems set this field to
+                       zero, indicating that the number of inodes is basically unlimited.
+                       Moreover it is not possible to reliably detect whether this is the
+                       case. Therefore this feature is disabled by default. It's safe to
+                       enable it for ext2/ext3/ext4 file systems on linux though.
+
+                       A value of zero (the default) deactivates this check.
+               [/help]
+       [option keep-redundant]
+               short_opt = k
+               summary = prune by disk space only
+               [help]
+                       By default, redundant and outdated snapshots are removed automatically
+                       to keep the number of snapshots in harmony with the configured
+                       policy. If this flag is given, dss removes such snapshots only if
+                       disk space or number of free inodes becomes low.
+               [/help]
+       [option min-complete]
+               summary = minimal number of complete snapshots to keep
+               arg_info = optional_arg
+               arg_type = uint32
+               typestr = num
+               default_val = 1
+               [help]
+                       This option is only relevant if snapshots must be deleted because
+                       disk space gets low.
+
+                       dss refuses to remove old snapshots if there are fewer complete
+                       snapshots left than the given number. The default value of one
+                       guarantees that at least one complete snapshot is available at
+                       all times.
+
+                       If only <num> complete snapshots are left, and there is not enough
+                       disk space available for another snapshot, the program terminates
+                       with a "No space left on device" error.
+               [/help]
+
+[introduction]
+       dss supports the subcommands described below. If no subcommand is
+       given, the list of available subcommands is shown and the program
+       terminates successfully without performing any further action.
+[/introduction]
+
+[subcommand run]
+       purpose = start creating and pruning snapshots
+       [description]
+               This is the main mode of operation. Snapshots are created in an endless
+               loop as needed and pruned automatically. The loop only terminates on
+               fatal errors or if a terminating signal was received. See also the
+               --exit-hook option.
+       [/description]
+       [option daemon]
+               short_opt = d
+               summary = run as background daemon
+               [help]
+                       If this option is given, the dss command detaches from the console
+                       and continues to run in the background. It is not possible to let
+                       a daemonized process re-attach to the console by editing the config
+                       file and sending SIGHUP. However, log output may be redirected to a
+                       different file in this way.
+
+                       See --logfile.
+               [/help]
+       [option logfile]
+               short_opt = l
+               summary = where to write log output
+               arg_info = required_arg
+               arg_type = string
+               typestr = path
+               default_val = /dev/null
+               [help]
+                       This option is only honored if --daemon is given, in which case
+                       log messages go to the given file. Otherwise the option is silently
+                       ignored and log output is written to stderr.
+               [/help]
+       [option max-rsync-errors]
+               summary = terminate after this many rsync failures
+               typestr = count
+               arg_info = required_arg
+               arg_type = uint32
+               default_val = 10
+               [help]
+                       If the rsync process exits with a fatal error, dss restarts the command
+                       in the hope that the problem is transient and subsequent rsync runs
+                       succeed. After the given number of consecutive rsync error exits,
+                       however, dss gives up, executes the exit hook and terminates. Set
+                       this to zero if dss should exit immediately on the first rsync error.
+
+                       The only non-fatal error is when rsync exits with code 24. This
+                       indicates a partial transfer due to vanished source files and happens
+                       frequently when snapshotting a directory which is concurrently being
+                       modified.
+               [/help]
+[subcommand create]
+       purpose = execute rsync once to create a new snapshot
+       [description]
+               This command does not check the amount free disk space. The pre-create
+               and post-create hooks are honored, however.
+
+               Specify --dry-run to see the rsync command which is executed to create
+               snapshots.
+       [/description]
+[subcommand prune]
+       purpose = remove snapshots
+       [description]
+               A snapshot is said to be (a) outdated if its interval number is greater
+               or equal than the specified number of unit intervals, (b) redundant if
+               the interval it belongs to contains more than the configured number of
+               snapshots, and (c) orphaned if it is incomplete and not being created
+               or deleted. All other snapshots are called regular.
+
+               Unless --dry-run is given, which just prints the snapshot that would be
+               removed, this subcommand gets rid of non-regular snapshots.  At most
+               one snapshot is removed per invocation. If no such snapshot exists
+               and disk space is low, the subcommand also removes regular snapshots,
+               always picking the oldest one.
+
+               The subcommand fails if there is another dss "run" process.
+       [/description]
+       [option disk-space]
+               summary = act as if free disk space was high/low
+               arg_info = required_arg
+               arg_type = string
+               typestr = mode
+               values = {
+                       FDS_CHECK = "check",
+                       FDS_HIGH = "high",
+                       FDS_LOW = "low"
+               }
+               default_val = check
+               [help]
+                       By default, free disk space is checked and even regular snapshots
+                       become candidates for removal if disk space is low. This option
+                       overrides the result of the check.
+               [/help]
+[subcommand ls]
+       purpose = print the list of all snapshots
+       [description]
+               The list contains all existing snapshots, no matter of their state.
+               Incomplete snapshots and snapshots being deleted will also be listed.
+       [/description]
+[subcommand kill]
+       purpose = send a signal to a running dss process
+       [description]
+               This sends a signal to the dss process that corresponds to the given
+               config file. If --dry-run is given, the PID of the dss process is
+               written to stdout, but no signal is sent.
+       [/description]
+       [option signal]
+               short_opt = s
+               summary = send the given signal rather than SIGTERM
+               typestr = signal
+               arg_info = required_arg
+               arg_type = string
+               default_val = SIGTERM
+               [help]
+                       Like for kill(1), alternate signals may be specified in three ways: as
+                       a signal number (e.g., 9), the signal name (e.g., KILL), or the signal
+                       name prefixed with "SIG" (e.g., SIGKILL). In the latter two forms,
+                       the signal name and the prefix are case insensitive, so "sigkill"
+                       works as well.
+
+                       Sending SIGHUP causes the running dss process to reload its config file.
+               [/help]
+       [option wait]
+               short_opt = w
+               summary = wait until the signalled process has terminated
+               [help]
+                       This option is handy for system shutdown scripts which would like
+                       to terminate the dss daemon process.
+
+                       Without --wait the dss process which executes the kill subcommand
+                       exits right after the kill(2) system call returns. At this point the
+                       signalled process might still be alive (even if SIGKILL was sent).
+                       If --wait is given, the process waits until the signalled process
+                       has terminated or the timeout expires.
+
+                       If --wait is not given, the kill subcommand exits successfully if
+                       and only if the signal was sent (i.e., if there exists another dss
+                       process to receive the signal). With --wait it exits successfully
+                       if, additionally, the signalled process has terminated before the
+                       timeout expires.
+
+                       It makes only sense to use the option for signals which terminate dss.
+               [/help]
+[subcommand configtest]
+       purpose = run a configuration file syntax test
+       [description]
+               This command checks the command line options and the configuration
+               file for syntactic correctness. It either reports "Syntax Ok" and
+               exits successfully or prints information about the first syntax error
+               detected and terminates with exit code 1.
+       [/description]
+
+[section copyright]
+       Written by AUTHOR()
+       .br
+       Copyright (C) 2008 - present AUTHOR()
+       .br
+       License: LICENSE()
+       .br
+       This is free software: you are free to change and redistribute it.
+       .br
+       There is NO WARRANTY, to the extent permitted by law.
+       .P
+       Project web page:
+       .UR URL()
+       .UE
+       .br
+       Git clone `URL':
+       .UR CLONE_URL()
+       .UE
+       .br
+       Gitweb:
+       .UR GITWEB_URL()
+       .UE
+       .br
+       Author's home page:
+       .UR HOME_URL()
+       .UE
+       .br
+       Report bugs to
+       .MT EMAIL()
+       AUTHOR()
+       .ME
+[/section]
+
+[section see also]
+       .BR ssh (1) ,
+       .BR rsync (1)
+[/section]
diff --git a/index.html.in b/index.html.in
deleted file mode 100644 (file)
index b505761..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
-       <title>DSS - The dyadic snapshot scheduler</title>
-       <LINK href="dss.css" REL="stylesheet" TYPE="text/css">
-       <link rel="shortcut icon" href="dss.ico">
-</head>
-
-<body>
-       <table>
-               <tr>
-                       <td>
-                               <img src="dss.svg" alt="dss">
-                       </td>
-                       <td>
-                               <h1>The dyadic snapshot scheduler</h1>
-                       </td>
-               </tr>
-       </table>
-
-       <hr>
-
-       [<a href="#readme">README</a>]
-       [<a href="#news">NEWS</a>]
-       [<a href="#download">Download</a>]
-       [<a href="#install">INSTALL</a>]
-       [<a href="#license">License</a>]
-       [<a href="#contact">Contact</a>]
-       [<a href="#manpage">Man page</a>]
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="readme">README</a>
-               </h2>
-       </center>
-
-       @README@
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="news">NEWS</a>
-               </h2>
-       </center>
-
-       @NEWS@
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="download">Download</a>
-               </h2>
-       </center>
-
-       <p>Only the source code is available for download. Use
-
-               <a href="http://www.kernel.org/pub/software/scm/git/docs/">git</a>
-
-       to clone the dss repository by executing</p>
-
-       <center>
-
-               <tt>git clone git://git.tuebingen.mpg.de/dss</tt>
-
-       </center>
-
-       <p> or grab the
-
-       <a href="http://git.tuebingen.mpg.de/cgi-bin/gitweb.cgi?p=dss.git;a=snapshot;h=HEAD;sf=tgz">tarball</a>
-
-       of the current master branch. If you prefer to download the tarball of
-       the latest release, select the corresponding <em>snapshot</em>
-       link on the
-
-               <a href="http://git.tuebingen.mpg.de/dss.git">dss gitweb page</a>
-
-       </p>
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="install">INSTALL</a>
-               </h2>
-       </center>
-
-       @INSTALL@
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="license">License</a>
-               </h2>
-       </center>
-
-       <p>dss is open source software, licensed under the
-
-       <a
-       href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU
-       General Public License, Version 2</a>.</p>
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="contact">Contact</a>
-               </h2>
-       </center>
-
-       <p> Email: Andr&eacute; Noll, <a
-       href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>,
-       Homepage: <a
-       href="http://people.tuebingen.mpg.de/maan/">http://people.tuebingen.mpg.de/maan/</a>
-       </p>
-
-       Comments and bug reports are welcome. Please provide
-       enough info such as the version of dss you are using and
-       relevant parts of the logs. Including the string [dss] in
-       the subject line is also a good idea.
-
-       <hr>
-
-       <center>
-               <h2>
-                       <a name="manpage">Man page</a>
-               </h2>
-       </center>
-
-       @MAN_PAGE@
-
-</body> </html>
-
diff --git a/index.html.m4 b/index.html.m4
new file mode 100644 (file)
index 0000000..6d2f58f
--- /dev/null
@@ -0,0 +1,99 @@
+dnl SPDX-License-Identifier: GPL-2.0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
+       <title>PACKAGE() - SLOGAN()</title>
+       <LINK href="dss.css" REL="stylesheet" TYPE="text/css">
+       <link rel="shortcut icon" href="dss.ico">
+</head>
+
+<body>
+       <table>
+               <tr>
+                       <td>
+                               <img src="dss.svg" alt="dss">
+                       </td>
+                       <td>
+                               <h1>SLOGAN()</h1>
+                       </td>
+               </tr>
+       </table>
+
+       <hr>
+
+       [<a href="#news">NEWS</a>]
+       [<a href="#install">INSTALL</a>]
+       [<a href="#license">License</a>]
+       [<a href="#resources">Resources</a>]
+       [<a href="#manpage">Man page</a>]
+
+       <hr>
+
+       <center>
+               <h2>
+                       <a name="readme">README</a>
+               </h2>
+       </center>
+
+       @README@
+
+       <hr>
+
+       <center>
+               <h2>
+                       <a name="news">NEWS</a>
+               </h2>
+       </center>
+
+       @NEWS@
+
+       <hr>
+
+       <center>
+               <h2>
+                       <a name="install">INSTALL</a>
+               </h2>
+       </center>
+
+       <p> To download the source code, run <tt> git clone CLONE_URL() </tt>,
+       or grab a current tarball from the <a href="GITWEB_URL()">gitweb
+       page</a> and unpack it. </p>
+
+       @INSTALL@
+
+       <hr>
+
+       <center>
+               <h2>
+                       <a name="license">License</a>
+               </h2>
+       </center>
+
+       <p> dss is open source software, licensed under the <a
+       href="LICENSE_URL()">LICENSE()</a>. </p>
+
+       <hr>
+
+       <center> <h2> <a name="resources">Resources</a> </h2> </center>
+       <ul>
+               <li> <a href="PACKAGE_HOMEPAGE()">PACKAGE() home page</a> </li>
+               <li> <code>git clone CLONE_URL()</code> </li>
+               <li> <a href="GITWEB_URL()">Gitweb</a> </li>
+               <li> <a href="HOME_URL()">Author home page</a> </li>
+               <li> Contact: <a href="mailto:EMAIL()">AUTHOR() &lt;EMAIL()&gt;</a> </li>
+       </ul>
+
+       <hr>
+
+       <center>
+               <h2>
+                       <a name="manpage">Man page</a>
+               </h2>
+       </center>
+
+       @MAN_PAGE@
+
+</body> </html>
+