#!/bin/sh

set -eu

tmpdir=$(mktemp -d)

src=
dst=

trap 'set +eu ; umount $src ; umount $dst ; mdconfig -d -u $src ; mdconfig -d -u $dst ; rm -rf $tmpdir' 0

size=20M

cleantable() {
	mount | fgrep $tmpdir/mnt2 && umount $tmpdir/mnt2 || :
	newfs -U $dst
	mount $dst $tmpdir/mnt2
}

: setting up create a file system
src=/dev/$(mdconfig -tswap -s$size)
newfs -U $src
mkdir $tmpdir/mnt1 $tmpdir/mnt2
mount $src $tmpdir/mnt1

# set up chroot
mkdir -p $tmpdir/mnt1/sbin
mkdir -p $tmpdir/mnt1/lib
mkdir -p $tmpdir/mnt1/libexec
mkdir -p $tmpdir/mnt1/bin
mkdir -p $tmpdir/mnt1/usr/local/sbin
cp /lib/libc.so.* /lib/libmd.so.* $tmpdir/mnt1/lib
cp /libexec/ld-*.so.* $tmpdir/mnt1/libexec
cp /usr/lib/libregex.so.* $tmpdir/mnt1/lib
cp -p /rescue/head $tmpdir/mnt1/bin
( cd $tmpdir/mnt1/bin && for i in sh ls sort ; do ln head $i ; done )
cp -p /usr/bin/find $tmpdir/mnt1/bin

date >$tmpdir/mnt1/sbin/file
# absolute symlink
ln -s /sbin/file $tmpdir/mnt1/usr/local/sbin/abssymlink
# relative symlink
ln -s ../../../sbin/file $tmpdir/mnt1/usr/local/sbin/relsymlink

# hardlinks to symlinks
( cd $tmpdir/mnt1/usr/local/sbin
  ln -P abssymlink hardlink-to-abssymlink
  ln -P relsymlink hardlink-to-relsymlink
)

: record mtree for verification
echo >$tmpdir/mtree.exclude .snap
mtree -c -R flags -p $tmpdir/mnt1 -X $tmpdir/mtree.exclude > $tmpdir/ref.mtree

#find $tmpdir/mnt1 -type d -o -print | sort | xargs ls -libdP

chroot $tmpdir/mnt1 sh -c "find / -type d -o -exec ls -libdP {} + ; head /usr/local/sbin/*symlink"

: create an target file system
dst=/dev/$(mdconfig -tswap -s$size)

printf '\n\n==> try to copy with dump/restore\n'
cleantable
( cd $tmpdir/mnt1 && dump -0Lf - $src ) | ( cd $tmpdir/mnt2 && restore -rf - ) || echo "### DUMP/RESTORE FAILED"
mtree -p $tmpdir/mnt2 -f $tmpdir/ref.mtree -e && echo "=== SUCCESS ===" || echo "### DUMP/RESTORE MTREE ERROR"

printf '\n\n==> try to copy with tar\n'
cleantable
( cd $tmpdir/mnt1 && tar --format pax -cf - . ) | ( cd $tmpdir/mnt2 && tar -xf - ) || echo "### TAR FAILED"
mtree -p $tmpdir/mnt2 -f $tmpdir/ref.mtree -e&& echo "=== SUCCESS ==="  || echo "### TAR MTREE ERROR"

printf '\n\n==> try to copy with gtar\n'
cleantable
( cd $tmpdir/mnt1 && gtar -H posix -cf - . ) | ( cd $tmpdir/mnt2 && gtar -H posix -xf - ) || echo "### GTAR FAILED"
mtree -p $tmpdir/mnt2 -f $tmpdir/ref.mtree -e && echo "=== SUCCESS ===" || echo "### GTAR MTREE ERROR"
