improve it in tree.
--- /dev/null
+# $OpenBSD: Makefile,v 1.1 2023/04/28 16:28:28 claudio Exp $
+
+regress:
+ sh ${.CURDIR}/runtests.sh ${.CURDIR}
+
+.include <bsd.regress.mk>
--- /dev/null
+rsync=${rsync-openrsync}
--- /dev/null
+#! /bin/sh
+
+set -u
+set -e
+
+# Library of functions.
+# Intended to be sourced by scripts (or interactive shells if you want).
+
+genfile_stdout_16m ()
+{
+ seq -f%015g 1048576
+}
+genfile_stdout_1m ()
+{
+ seq -f%015g 65536
+}
+genfile ()
+{
+ #touch "$1"
+ genfile_stdout_1m > "$1"
+}
+
+# makes a directory path and optionally a file in it.
+# if you want the last element to be a directory, add / at the end
+mkdirfile ()
+{
+ case "$1" in
+ '') error that cannot work;;
+ */) mkdir -p "$1";;
+ */*) mkdir -p "${1%/*}"; genfile "$1";;
+ *) genfile "$1";;
+ esac
+}
+
+mkdirsymlink ()
+{
+ (
+ mkdir -p "$1"
+ cd "$1"
+ ln -sf "$2" "$3"
+ )
+}
+
+# make a first interesting tree
+generate_tree_1 ()
+{
+ mkdirfile foo/bar/baz/one.txt
+ mkdirfile foo/bar/baz/one2.txt
+ mkdirfile 'foo/bar/baz/ two.txt'
+ mkdirfile 'foo/bar/baz/two 2.txt'
+ mkdirfile 'foo/bar/baz/two3.txt '
+ mkdirsymlink foo/baz/ ../bar/baz/one.txt three.txt
+ mkdirfile one/two/three/four.txt
+ mkdirfile foo/five/one/two/five/blah.txt
+ mkdirfile foo/one/two/five/blah.txt
+}
+
+# a frontend for find
+# first argument is a dir to chdir to
+findme ()
+{
+ if [ $# -lt 2 ] ; then
+ echo usage: different 1>&2
+ return 1
+ fi
+ (
+ cd "$1" ; shift
+ # Cut out the inode number and blocks used.
+ # Maybe later also cut out size in bytes for directories.
+ find "$@" -ls | sed 's/^ *[0-9]* *[0-9]* *//' | sort
+ )
+}
+
+# compare two trees. This will later be modular to pick between:
+# - diff
+# - find . -print0 | sort --zero-terminated | xargs -0 tar fc foo.tar
+# - mtree
+compare_trees ()
+{
+ if [ $# -ne 2 ] ; then
+ echo usage: different 1>&2
+ return 1
+ fi
+ # files_and_permissions
+ findme "$1" . > find1
+ findme "$2" . > find2
+ diff -u find[12]
+ # file contents
+ diff -ru "$1" "$2"
+}
--- /dev/null
+#!/bin/sh
+
+for i in ${1}/*.test; do
+ echo $(basename ${i})
+ tstdir=${1} sh ${i}
+ if [ "$?" -eq "0" ]; then
+ echo OK
+ else
+ echo FAIL
+ fi
+done
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+mkdir dir1
+cd dir1
+generate_tree_1
+
+cd ../..
+$rsync -a dir1 dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+umask 022
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+chmod 640 foo/bar/baz/one.txt
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+genfile one.txt
+# we expect umask permissions after rsync
+chmod 644 one.txt
+
+mkdir ../dir3
+cd ../dir3
+genfile one.txt
+# we expect umask permissions after rsync
+chmod 644 one.txt
+
+cd ..
+# call -a without -p
+$rsync -Dgorltr dir1/foo/bar/baz/one.txt dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+umask 022
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+chmod 640 foo/bar/baz/one.txt
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+genfile one.txt
+# we expect the file's original permissions (not umask)
+# when the target did not exist.
+chmod 640 one.txt
+
+mkdir ../dir3
+
+cd ..
+# call -a without -p
+$rsync -Dgorltr dir1/foo/bar/baz/one.txt dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+umask 022
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+rm foo/baz/three.txt
+# make this file again the way we want it.
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo foo >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+rm foo/baz/three.txt
+# make this file again the way we want it.
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo foo >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+
+mkdir ../dir3
+cd ../dir3
+generate_tree_1
+rm foo/baz/three.txt
+# make this file different in the middle
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo bar >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+
+cd ..
+# openrsync needs the --ignore-times here since it doesn't have
+# a flag to force checksumming.
+echo $rsync -a --ignore-times dir1/ dir3
+$rsync --rsync-path openrsync -a --ignore-times dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# this test is a bit easier than test11 since the file size differs
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+umask 022
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+rm foo/baz/three.txt
+# make this file again the way we want it.
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo foo >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+echo baz >> foo/bar/baz/one.txt
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+rm foo/baz/three.txt
+# make this file again the way we want it.
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo foo >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+echo baz >> foo/bar/baz/one.txt
+
+mkdir ../dir3
+cd ../dir3
+generate_tree_1
+rm foo/baz/three.txt
+# make this file different in the middle
+dd if=/dev/zero bs=1m count=1 status=none > foo/bar/baz/one.txt
+echo bar >> foo/bar/baz/one.txt
+dd if=/dev/zero bs=1m count=1 status=none >> foo/bar/baz/one.txt
+
+cd ..
+# openrsync needs the --ignore-times here since it doesn't have
+# a flag to force checksumming.
+$rsync -a --ignore-times dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+find . -type f \! -name '???.txt' -exec rm {} \;
+rm foo/baz/three.txt
+
+cd ..
+$rsync -a --include='???.txt' --include='*/' --exclude='*' dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+mkdirfile meh.txt
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+mkdirfile meh.txt
+
+cd ..
+$rsync -a --exclude='*/' dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+find . -type f \! -name '*.txt' -exec rm {} \;
+
+cd ..
+$rsync -a --include='*.txt' --include='*/' --exclude='*' dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+
+cd ..
+$rsync -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm one/two/three/four.txt
+
+cd ..
+$rsync --exclude 'four.txt' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm foo/bar/baz/' two.txt'
+
+cd ..
+$rsync --exclude ' two.txt' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm 'foo/bar/baz/ two.txt'
+
+cd ..
+$rsync --exclude ' *' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm foo/bar/baz/*' '*
+
+cd ..
+$rsync --exclude '* *' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm foo/bar/baz/*' '
+
+cd ..
+$rsync --exclude '* ' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm foo/bar/baz/two3.txt' '
+
+cd ..
+$rsync --exclude 'two3.txt ' -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing --exclude basics
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+# manually delete the file that should be missing after rsync
+rm one/two/three/four.txt
+rmdir one/two/three
+
+cd ..
+$rsync --exclude two/three -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+
+# Also make the target tree and mess up some permissions in there.
+# We expect rsync to reset this to what dir1 has.
+mkdir ../dir3
+cd ../dir3
+generate_tree_1
+chmod 600 foo/bar/baz/one.txt
+chmod 070 foo/bar/baz/one2.txt
+
+cd ..
+$rsync -a dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# Testing that rsync -a without -p indeed leaves permissions alone.
+# Make the target tree and mess up some permissions in there.
+# We expect rsync to NOT reset this to what dir1 has since we don't
+# use -a.
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+chmod 600 foo/bar/baz/one.txt
+chmod 777 foo/bar/baz/one2.txt
+
+mkdir ../dir3
+cd ../dir3
+generate_tree_1
+chmod 600 foo/bar/baz/one.txt
+chmod 777 foo/bar/baz/one2.txt
+
+cd ..
+# call -a without -p.
+$rsync -Dglort dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# see end of file for comment
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+
+mkdir ../dir3
+cd ../dir3
+generate_tree_1
+
+cd ..
+# call -a without -l.
+# pre-existing symlink should be gone?
+$rsync --delete -Dgortp dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# see end of file for comment
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+generate_tree_1
+rm foo/baz/three.txt
+
+cd ..
+# call -a without -l.
+# we expect no symlink to be in the target tree
+$rsync -Dgortp dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing modification time. This is tricky for two reasons:
+# - BSD find only emits minutes granularity
+# - the test might run less than a second, but the rsync
+# protocol has 1 second roundoff in times
+# So we set some time older than this software for some
+# parts of the original tree.
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+touch -d 1975-10-21T01:01:01 foo
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+touch -d 1975-10-21T01:01:01 foo
+
+# test a - we want the time corrected
+mkdir ../dir3
+cd ../dir3
+touch -d 1975-10-21T01:01:01 foo
+
+cd ..
+# call -a
+$rsync -Dgorltp dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+# testing modification time. This is tricky for two reasons:
+# - BSD find only emits minutes granularity
+# - the test might run less than a second, but the rsync
+# protocol has 1 second roundoff in times
+# So we set some time older than this software for some
+# parts of the original tree.
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+touch -d 1976-10-21T01:01:01 foo
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+touch foo
+
+# test b - we want the time set to the current time by rsync
+mkdir ../dir3
+cd ../dir3
+touch -d 1975-10-21T01:01:01 foo
+
+cd ..
+# call -a without -t
+$rsync -Dgorlp dir1/ dir3
+compare_trees dir2 dir3
--- /dev/null
+#! /bin/sh
+
+. ${tstdir-.}/lib.sh
+. ${tstdir-.}/conf.sh
+
+rm -rf dir1 dir2 dir3
+# make the copy-from-here tree
+mkdir dir1
+cd dir1
+generate_tree_1
+# make the tree we want to compare to
+mkdir ../dir2
+cd ../dir2
+genfile one.txt
+
+mkdir ../dir3
+
+cd ..
+# call -a without -r
+$rsync -Dgorltp dir1/foo/bar/baz/one.txt dir3
+compare_trees dir2 dir3