]> git.tuebingen.mpg.de Git - dss.git/commitdiff
Merge topic branch t/com_help into pu
authorAndre Noll <maan@tuebingen.mpg.de>
Thu, 23 May 2024 14:56:22 +0000 (16:56 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Thu, 23 May 2024 14:56:22 +0000 (16:56 +0200)
Started on 2024-04-28

* refs/heads/t/com_help:
  Implement help subommand.

# Conflicts:
# dss.c
# dss.suite.m4

1  2 
dss.c
dss.suite.m4

diff --cc dss.c
index 77b2dc558396e943cb2c58c32947c36e21c54c1f,06e0d6a11612e0706d1b4e22495512f2a8cba779..7a2e1e76203a09529bc7dde6aa3df3184203ab14
--- 1/dss.c
--- 2/dss.c
+++ b/dss.c
@@@ -1825,6 -1824,10 +1825,10 @@@ static void handle_version_and_help(voi
  {
        char *txt;
  
 -              printf(VERSION_STRING "\n");
+       if (OPT_GIVEN(DSS, VERSION)) {
++              printf("%s\n", dss_version());
+               exit(EXIT_SUCCESS);
+       }
        if (OPT_GIVEN(DSS, DETAILED_HELP))
                txt = lls_long_help(CMD_PTR(DSS));
        else if (OPT_GIVEN(DSS, HELP))
diff --cc dss.suite.m4
index 27437f443563c8ea146f7732a9c700bdabad4392,0000000000000000000000000000000000000000..3fe3122b6b619bcfa600a4ce61ab31b292f4415a
mode 100644,000000..100644
--- /dev/null
@@@ -1,668 -1,0 +1,684 @@@
 +# 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
 +      [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]
++[subcommand help]
++      purpose = list available subcommands or print subcommand-specific help
++      non-opts-name = [subcommand]
++      [description]
++              If the optional subcommand argument is given, the help text of that
++              subcommand is shown. Without the argument the available subcommands
++              are listed instead.
++      [/description]
++      [option long]
++              short_opt = l
++              summary = show the long help text of a subcommand
++              [help]
++                      If this option is given, the command also shows the description of
++                      the subcommand and the help text of each option, Otherwise only the
++                      purpose, the synopsis and the option list of the subcommand is shown.
++                      If no subcommand is supplied, the option has no effect.
++              [/help]
 +
 +[section examples]
 +      Suppose you'd like to create snapshots of the existing directory
 +      .I /foo/bar
 +      in the directory
 +      .IR /baz/qux .
 +      Create the config file
 +      .I ~/.dssrc
 +      containing
 +      the values for the source and the destination directories
 +      as follows:
 +
 +      .RS 6
 +      .EX
 +              echo 'source-dir "/foo/bar"' > ~/.dssrc
 +              echo 'dest-dir "/baz/qux"' >> ~/.dssrc
 +      .EE
 +      .RE
 +
 +      Then execute the commands
 +
 +      .RS 6
 +      .EX
 +              mkdir /baz/qux
 +              dss run
 +      .EE
 +      .RE
 +
 +      To print the list of all snapshots created so far, run
 +      .IR dss\~ls .
 +
 +      The second example involves a slightly more sophisticated config
 +      file. It instructs dss to exclude everything which matches at least
 +      one pattern of the given exclude file, prevents rsync from crossing
 +      file system boundaries and increases the number of snapshots.
 +
 +      .RS 6
 +      .EX
 +              source-dir "/foo/bar"
 +              dest-dir "/baz/qux"
 +              # exclude files matching patterns in /etc/dss.exclude
 +              rsync-option \-\-exclude\-from=/etc/dss.exclude
 +              # don't cross filesystem boundaries
 +              rsync-option \-\-one\-file\-system
 +              # maintain 2^6 - 1 = 63 snapshots
 +              num-intervals "6"
 +      .EE
 +      .RE
 +
 +      The
 +      .I /etc/dss.exclude
 +      file could look like this (see rsync(1) for more examples)
 +
 +      .RS 6
 +      .EX
 +               - /proc
 +               - /**/tmp/
 +      .EE
 +      .RE
 +[/section]
 +
 +[section snapshot distribution]
 +      The age of a snapshot is measured in terms of unit
 +      intervals. Given
 +      the duration
 +      .I u
 +      of a unit
 +      interval and the number
 +      .I n
 +      of unit intervals to consider, dss tries to keep
 +      .I 2^(n-k-1)
 +      snapshots in interval
 +      .IR k ,
 +      where the interval number
 +      .I k
 +      counts
 +      from zero to
 +      .IR n-1 ,
 +      with zero being the most recent unit interval. Snapshots older than
 +      .I n
 +      unit intervals are regarded as outdated and are removed. There are
 +      .I 2^n-1
 +      snapshots in total.
 +
 +      For example, with four unit intervals, the 2^4 - 1 = 15 snapshots
 +      are distributed as follows.
 +
 +      .TS
 +      allbox;
 +      lb r r r r
 +      lb r r r r.
 +      Interval        3       2       1       0
 +      Snapshots       \~\~\~\~*\~\~\~ \~\~*\~\~*\~\~  \~*\~*\~*\~*    ********
 +      .TE
 +
 +      Note that for this to work out the system must be fast enough to
 +      create at least
 +      .I 2^(n-1)
 +      snapshots per unit interval because this is the number of snapshots
 +      in interval zero.
 +[/section]
 +
 +[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]