+
+ # Build a helper script to ignore exit code 23
+ ignore23="$scratchdir/ignore23"
+ echo "building help script $ignore23"
+
+ cat >"$ignore23" <<'EOT'
+if "${@}"; then
+ exit
+fi
+
+ret=$?
+
+if test $ret = 23; then
+ exit
+fi
+
+exit $ret
+EOT
+chmod +x "$ignore23"
+}
+
+
+build_symlinks() {
+ mkdir "$fromdir"
+ date >"$fromdir/referent"
+ ln -s referent "$fromdir/relative"
+ ln -s "$fromdir/referent" "$fromdir/absolute"
+ ln -s nonexistent "$fromdir/dangling"
+ ln -s "$srcdir/rsync.c" "$fromdir/unsafe"
+}
+
+test_fail() {
+ echo "$@" >&2
+ exit 1
+}
+
+test_skipped() {
+ echo "$@" >&2
+ echo "$@" > "$tmpdir/whyskipped"
+ exit 77
+}
+
+# It failed, but we expected that. don't dump out error logs,
+# because most users won't want to see them. But do leave
+# the working directory around.
+test_xfail() {
+ echo "$@" >&2
+ exit 78
+}
+
+# Determine what shell command will appropriately test for links.
+ln -s foo "$scratchdir/testlink"
+for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test
+do
+ for switch in -h -L
+ do
+ if $cmd $switch "$scratchdir/testlink" 2>/dev/null
+ then
+ # how nice
+ TEST_SYMLINK_CMD="$cmd $switch"
+ # i wonder if break 2 is portable?
+ break 2
+ fi
+ done
+done
+# ok, now get rid of it
+rm "$scratchdir/testlink"
+
+
+if [ "x$TEST_SYMLINK_CMD" = 'x' ]
+then
+ test_fail "Couldn't determine how to test for symlinks"
+else
+ echo "Testing for symlinks using '$TEST_SYMLINK_CMD'"
+fi
+
+
+# Test whether something is a link, allowing for shell peculiarities
+is_a_link() {
+ # note the variable contains the first option and therefore is not quoted
+ $TEST_SYMLINK_CMD "$1"