#!/bin/sh

# quit at first sign of trouble
set -e

# set up test conditions
echo -n "checking mirroring of simple files and directories... "
rm -rf test-control test-mirror
mkdir test-control
cp ../[A-Zc]* test-control
mkdir test-control/stuff
cp m* test-control/stuff
mkdir test-control/empty-dir
touch test-control/empty-file
chown 1.2 test-control/empty-file >/dev/null 2>&1 || true
mkdir test-mirror
# first test run
./mirrordir test-control test-mirror
# simple test
if diff -r test-control test-mirror; then echo pass;
else echo fail; exit 1; fi

# make minor changes
mv test-mirror/README test-mirror/XXX
# sleep so time stamp is really changed
sleep 2; touch test-control/Makefile.in
mkfifo test-control/pipe
echo -n "checking whether only minimal copying is done... "
# remove path (which may be different on build machine) and total of
# bytes copied (which may change with each mirrordir release)
./mirrordir --verbose test-control test-mirror | \
           sed -e 's|/.*/||' -e 's/mirrored.*kB$//' >test-log
cat >test-ok <<EOF
mirrordir: ---verbose--- copying file: Makefile.in
mirrordir: ---verbose--- copying file: README
mirrordir: ---verbose--- creating device file: pipe
mirrordir: ---verbose--- removing file: XXX
mirrordir: ---verbose--- all hardlinks located
mirrordir: Total 
EOF
if diff test-ok test-log; then echo pass;
else echo fail; exit 1; fi

# do detailed comparison because diff ignores dates and fails on pipes
detailedcheck(){
    for DIR in control mirror; do
	cd test-$DIR; ls $LFLAGS | awk '
	    /^l/{for(i=1;i<11;i++){if($i~/\:/) $i="";}}
	    {print}
' > ../ls-$DIR; cd ..
    done
    diff ls-control ls-mirror >& diff-error
    if [ -s diff-error ] ; then
	echo fail;
	cat diff-error;
	exit 1;
    fi
    echo pass
}

echo -n "checking mirroring of pipes and file dates... "
detailedcheck

echoname(){
    case "$1" in
	1)  echo -n a normal file; ;;
	2)  echo -n an empty file; ;;
	3)  echo -n a normal directory; ;;
	4)  echo -n an empty directory; ;;
	5)  echo -n a broken symlink; ;;
	6)  echo -n a symlink to file; ;;
	7)  echo -n a symlink to directory; ;;
	8)  echo -n nothing; ;;
	9)  echo -n a pipe; ;;
	10)  echo -n a device; ;;
	11)  echo -n a socket; ;;
    esac
}

makething(){
    case "$1" in
	1)  echo stuff >test-control/thing$2; ;;
	2)  touch test-control/thing$2; ;;
	3)  mkdir test-control/thing$2; touch test-control/thing$2/foo;;
	4)  mkdir test-control/thing$2; ;;
	5)  ln -s nowhere test-control/thing$2; ;;
	6)  ln -s Makefile test-control/thing$2; ;;
	7)  ln -s directory test-control/thing$2; ;;
	8)  ;;
	9)  mkfifo test-control/thing$2; ;;
	10)  mknod test-control/thing$2 b 2 3; ;;
	11)  ./mksock test-control/thing$2; ;;
    esac

    PERM=`awk '
BEGIN{printf("7%d%d",ARGV[1]%7,(ARGV[1]+3)%7)}' $1`;
    chmod $PERM test-control/thing$2 >/dev/null 2>&1 || true;
    
    if [ "$3" = "two" ]; then 
	ln test-control/thing$2 "test-control/link $2" >/dev/null 2>&1 || true;
    fi
}

rm -rf ls-* test-*
mkdir test-control
mkdir test-orig
mkdir test-mirror

echo -n "check whether I am root... "
if [ $UID = 0 ]; then echo yes; TEN=10; ELEVEN=11;
else 
    echo "no (so I will skip chown, device, and socket tests)";
    TEN=; ELEVEN=; 
fi

if [ "$PASSWORD" != "" ]; then
    echo -n "check mirroring an ftp site... "
    rm -rf test-control/* test-mirror/*
    cp M* test-control
    mkdir test-control/directory
    for y in 1 2 3 4 5 6 7 8 $TEN; do makething $y $y one; done
    ./mirrordir --password "$PASSWORD" \
    	ftp://$USER@localhost`pwd`/test-control test-mirror
    LFLAGS="-lR"
    detailedcheck

    echo -n "check uploading to an ftp site... "
    rm -rf test-control/* test-mirror/*
    cp M* test-control
    mkdir test-control/directory
    for y in 1 2 3 8; do makething $y $y one; done
    ./mirrordir --password "$PASSWORD" \
    	test-control ftp://$USER@localhost`pwd`/test-mirror
    LFLAGS="-lR"
    detailedcheck
fi

echo -n "check whether ls accepts --full-time switch... "
if ls -l --full-time >/dev/null; then echo yes; LFLAGS="-lR --full-time";
else echo no; LFLAGS="-lR"; fi;

echo -n "check whether --dry-run prevents removal of things... "
rm -rf ls-* test-*
mkdir test-control
mkdir test-mirror
cp M* test-control
mkdir test-control/directory
for y in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do makething $y $y two; done
chown 1.2 test-control/thing1 >/dev/null 2>&1 || true
./mirrordir test-mirror test-control
mkdir test-empty
./mirrordir --dry-run test-empty test-control
detailedcheck

if [ $UID = 0 ]; then
    echo -n "check whether --no-chmod and --no-chown prevent changes... "
else
    echo -n "check whether --no-chmod prevents mode changes... "
fi
rm -rf ls-* test-*
mkdir test-control
mkdir test-orig
mkdir test-mirror
for x in able baker charlie delta; do touch test-control/$x; done
mirrordir test-control test-orig
mirrordir test-control test-mirror
if [ $UID = 0 ]; then chown 3.4 test-orig/able test-orig/charlie; fi
chmod 444 test-orig/baker test-orig/charlie
mirrordir --no-chmod --no-chown test-orig test-mirror
detailedcheck

echo -n "check whether --dry-run prevents copying... "
rm -rf ls-* test-*
mkdir test-control
mkdir test-mirror
cp M* test-control
mkdir test-control/directory
for y in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do makething $y $y two; done
chown 1.2 test-control/thing1 >/dev/null 2>&1 || true
./mirrordir --dry-run test-control test-mirror
rm -rf ls-* test-control
mkdir test-control
detailedcheck

echo -n "check mirroring of doubly linked things... "
rm -rf test-control/* test-mirror/*
cp M* test-control
mkdir test-control/directory
for y in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do makething $y $y two; done
chown 1.2 test-control/thing1 >/dev/null 2>&1 || true
./mirrordir test-control test-mirror
detailedcheck

# check many combinations of replacing one thing with another
rm -rf ls-* test-*
mkdir test-control
mkdir test-orig
mkdir test-mirror
for links in one two; do
    echo "with $links link(s) per entry..."
    for x in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do
    	echo -n "  check replacement of `echoname $x` by various things... "
    	rm -rf test-control/* test-mirror/* test-orig/*
    	cp M* test-control
	mkdir test-control/directory
    	for y in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do makething $x $y $links; done
	sleep 1
    	e1=`./mirrordir --verbose test-control test-mirror | grep 'all hardlinks located'`
    	e2=`./mirrordir --verbose test-control test-orig | grep 'all hardlinks located'`
	if [ -z "$e1" -o -z "$e2" ] ; then echo fail ; exit 1 ; fi
    	for y in 1 2 3 4 5 6 7 8 $TEN $ELEVEN; do \
    	    rm -rf test-control/thing$y; makething $y $y none; done
    	./mirrordir test-control test-mirror
	detailedcheck
	 if [ "$links" = "two" ]; then
	     echo -n "  check replacement of various things by `echoname $x`... "
	     ./mirrordir test-orig test-control
	     ./mirrordir test-control test-mirror
	     detailedcheck
	 fi
    done
done

rm -rf ls-* test-*


