#! /usr/bin/tclsh

# WARNING!!!!!!!
# This script erases the partition on which it runs the test.
# It is used for testing purposes only.  Use with great caution.
# I use it for my testing purposes.
 
# Script to check all kinds of possibilities.
# There are a few known problems with internationalization related
# things.  I haven't had time to fix them properly yet.

#set testdrive /dev/fd0
#set testdrive /dev/sdb4
#set testdrive /dev/hda6
set testdrive /dev/sdb1
set interactive 0
set runs 30

proc mountx {{opts {}}} {
	global testdrive
	catch {exec umount /mnt}
	if {$opts != {}} {
	    exec mount -t vfat -o $opts $testdrive /mnt
	} else {
	    exec mount -t vfat $testdrive /mnt
	}
}

proc mountm {{opts {}}} {
	global testdrive
	catch {exec umount /mnt}
	if {$opts != {}} {
	    exec mount -t msdos -o quiet,$opts $testdrive /mnt
	} else {
	    exec mount -t msdos -o quiet $testdrive /mnt
	}
}

proc erasedisk {} {
	eval exec rm -fr [glob -nocomplain /mnt/.\[a-z\]* /mnt/*]
}

proc runtest {version body answer args} {
	global interactive
	if {$interactive} {
		puts -nonewline stdout "Run test $version? "
		gets stdin yn
		if {[string range $yn 0 1] == "n"} {
			return
		}
	}
	if [catch {set result [eval $body]} error] {
		global errorInfo
		puts "    - vfat test $version failed: $error $errorInfo"
	} elseif {[string compare $result $answer] != 0} {
		puts "    - vfat test $version failed"
		puts "      Result was:"
		puts "      --------------------------------------------------"
		puts "      $result"
		puts "      Result should have been:"
		puts "      --------------------------------------------------"
		puts "      $answer"
		puts ""
	} else {
		puts "    + vfat test $version succeeded"
	}
}

proc dirRecurseCheck {dir1 dir2} {
    cd $dir1
    set files1 [lsort [glob -nocomplain *]]
    cd $dir2
    set files2 [lsort [glob -nocomplain *]]
    if {[string compare $files1 $files2] != 0} {
	puts "   Files in $dir1 are not the same as $dir2"
	puts "   $dir1: $files1"
	puts "   $dir2: $files2"
    }
    set dirs [lsort [glob -nocomplain */]]

    foreach dir $dirs { 
	set newdir1 [format "%s%s" $dir1 $dir]
	set newdir2 [format "%s%s" $dir2 $dir]
        dirRecurseCheck $newdir1 $newdir2
    }
}

# One problem in running this more than once is that the inodes do
# not get flushed.  Since they don't get flushed, not all the directory
# entries can be created since the entries are marked busy.  Need to
# find a way to force flushing of the inodes.  Even umounting and 
# remounting the disk does not force flushing of the inodes.  This
# seems rather dangerous to me.

for {set run 1} {$run <= $runs} {incr run} {
    puts ""
    puts "Iteration #$run of $runs"

if {1} {
    mountx
    erasedisk
    puts "  Shortname Tests between vfat and msdos"
    puts "  ----------------------------------------------------------------------"

    #----------------------------------------------------------------------
    puts "  Testing creation of standard shortnames"
    set flist {/mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}
    runtest 1.0 {
	global flist
        eval exec touch $flist
        lsort [glob -nocomplain /mnt/*]
    } [lsort $flist] {}

    mountm
    runtest 1.1 {
	set result [lsort [glob -nocomplain /mnt/*]]
    } [lsort $flist] {}

    #----------------------------------------------------------------------
    # The volume name entry can cause a bit of a problem.  Only create 
    # 223 names.
    catch {unset filelist1 filelist2}
    for {set i 0} {$i < 223} {incr i} {
	lappend filelist1 /mnt/test$i
	lappend filelist2 /mnt/test$i
    }

    mountx
    puts "  testing creation of lots of files"
    # Before doing this, force flushing of active inodes.
    runtest 1.2 {
	global filelist1
	erasedisk
	eval "exec touch $filelist1"
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist1] {}

    mountm
    runtest 1.3 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist2] {}

    #----------------------------------------------------------------------

    mountx
    puts "  checking for limited space in root directory if testdrive is a floppy"
    runtest 1.4 {
	global testdrive
	catch {exec touch /mnt/test223} error
	catch {exec touch /mnt/test224} error
	if {[string first /dev/fd $testdrive] == 0} {
	    set error
	} else {
	    set error {touch: /mnt/test224: No space left on device}
	}
    } {touch: /mnt/test224: No space left on device}

    #----------------------------------------------------------------------

    mountx
    erasedisk
    puts "  testing renaming of shortnames"
    runtest 1.5 {
	catch {exec touch /mnt/test1.tst /mnt/test2.tst /mnt/test3.tst}
	catch {exec mv /mnt/test1.tst /mnt/test4.tst}
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test2.tst /mnt/test3.tst /mnt/test4.tst}] {}

    runtest 1.6 {
	catch {exec mv /mnt/test3.tst /mnt/test2.tst}
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test2.tst /mnt/test4.tst}] {}

    mountm
    runtest 1.7 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test2.tst /mnt/test4.tst}] {}

    mountx
    runtest 1.8 {
	exec echo test > /mnt/x
	exec cp -f /mnt/x /mnt/y
	exec rm -f /mnt/x
	exec mv /mnt/y /mnt/x
	set size [file size /mnt/x]
	exec rm -f /mnt/x
	set size
    } 5 {}

    #----------------------------------------------------------------------
    puts "  testing deleting of shortnames"
    mountx
    runtest 1.9 {
	catch {exec rm /mnt/test2.tst}
	lsort [glob -nocomplain /mnt/*]
    } /mnt/test4.tst

    mountm
    runtest 1.10 {
	lsort [glob -nocomplain /mnt/*]
    } /mnt/test4.tst

    mountx
    runtest 1.11 {
	catch {exec rm /mnt/test4.tst}
	lsort [glob -nocomplain /mnt/*]
    } {}

    mountm
    runtest 1.12 {
	lsort [glob -nocomplain /mnt/*]
    } {}
    #----------------------------------------------------------------------

    puts "  testing directory creation"
    mountx
    runtest 1.13 {
	catch {exec mkdir /mnt/jane /mnt/harry /mnt/spot /mnt/rover.run}
	catch {exec touch /mnt/test.fil}
	lsort [glob -nocomplain /mnt/*/]
    } [lsort {/mnt/jane/ /mnt/harry/ /mnt/spot/ /mnt/rover.run/}] {}

    runtest 1.14 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/jane /mnt/harry /mnt/spot /mnt/rover.run /mnt/test.fil}] {}

    mountm
    runtest 1.15 {
	lsort [glob -nocomplain /mnt/*/]
    } [lsort {/mnt/jane/ /mnt/harry/ /mnt/spot/ /mnt/rover.run/}] {}

    runtest 1.16 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/jane /mnt/harry /mnt/spot /mnt/rover.run /mnt/test.fil}] {}

    #----------------------------------------------------------------------
    puts "  testing moving files around directories"
    mountx
    runtest 1.17 {
	catch {exec touch /mnt/test1.fil /mnt/test2.fil /mnt/test3.fil}
	catch {exec mv /mnt/test1.fil /mnt/test2.fil /mnt/rover.run}
	lsort [glob -nocomplain /mnt/rover.run/*]
    } [lsort {/mnt/rover.run/test1.fil /mnt/rover.run/test2.fil}] {}

    runtest 1.18 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/jane /mnt/harry /mnt/spot /mnt/rover.run /mnt/test.fil /mnt/test3.fil}] {}

    mountm
    runtest 1.19 {
	lsort [glob -nocomplain /mnt/rover.run/*]
    } [lsort {/mnt/rover.run/test1.fil /mnt/rover.run/test2.fil}] {}

    runtest 1.20 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/jane /mnt/harry /mnt/spot /mnt/rover.run /mnt/test.fil /mnt/test3.fil}] {}

    mountx
    runtest 1.21 {
	catch {exec mv /mnt/rover.run/test2.fil /mnt/spot}
	lsort [glob -nocomplain /mnt/spot/*]
    } /mnt/spot/test2.fil {}

    runtest 1.22 {
	lsort [glob -nocomplain /mnt/rover.run/*]
    } /mnt/rover.run/test1.fil {}

    puts "  testing directory moving"
    runtest 1.23 {
	catch {exec mv /mnt/jane /mnt/spot}
	lsort [glob -nocomplain /mnt/spot/*]
    } [lsort {/mnt/spot/test2.fil /mnt/spot/jane}] {}

    runtest 1.24 {
	lsort [glob -nocomplain /mnt/spot/*/]
    } /mnt/spot/jane/ {}

    runtest 1.25 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/harry /mnt/spot /mnt/rover.run /mnt/test.fil /mnt/test3.fil}] {}

    runtest 1.26 {
	catch {exec mv /mnt/spot/jane /mnt/harry}
	lsort [glob -nocomplain /mnt/spot/*/]
    } {}

    runtest 1.27 {
	lsort [glob -nocomplain /mnt/harry/*]
    } /mnt/harry/jane {}

    runtest 1.28 {
	catch {exec mkdir /mnt/harry/dir2}
	lsort [glob -nocomplain /mnt/harry/*]
    } [lsort {/mnt/harry/jane /mnt/harry/dir2}] {}

    mountm
    runtest 1.29 {
	lsort [glob -nocomplain /mnt/harry/*]
    } [lsort {/mnt/harry/jane /mnt/harry/dir2}] {}

    mountx
    runtest 1.30 {
	catch {exec mv /mnt/harry /mnt/harry}
	lsort [glob -nocomplain /mnt/harry/*]
    } [lsort {/mnt/harry/jane /mnt/harry/dir2}] {}

    mountx
    runtest 1.31 {
	exec mkdir /mnt/demi
	exec echo aaaa > /mnt/demi/a0
	exec echo bbbb > /mnt/demi/b0
	exec mv /mnt/demi/a0 /mnt/demi/a1
	exec mv /mnt/demi/b0 /mnt/demi/b1
	exec cat /mnt/demi/a1 /mnt/demi/b1
    } {aaaa
bbbb}

    runtest 1.32 {
	exec mv /mnt/demi/a1 /mnt/demi/a2
	exec mv /mnt/demi/b1 /mnt/demi/b2
	exec cat /mnt/demi/a2 /mnt/demi/b2
    } {aaaa
bbbb}

    runtest 1.33 {
	exec mkdir /mnt/rumor
	exec echo a > /mnt/rumor/a
	exec mv /mnt/rumor/a /mnt/rumor/x
	exec mv /mnt/rumor/x /mnt/rumor/a
        exec cat /mnt/rumor/a
    } {a}

    #----------------------------------------------------------------------
    #----------------------------------------------------------------------

    puts ""
    puts "  Longname Tests"
    puts "  ----------------------------------------------------------------------"

    catch {unset filelist1 filelist2}
    set file ""
    for {set i 97} {$i < 123} {incr i} {
	set file [format "%s%c" $file $i]
	lappend filelist1 /mnt/$file
    }

    set file ""
    for {set i 66} {$i < 91} {incr i} {
	set file [format "%s%c" $file $i]
	lappend filelist2 /mnt/$file
    }

    #----------------------------------------------------------------------
    erasedisk
    mountx check=s
    puts "  Testing creation of longnames"
    runtest 2.0 {
	global filelist1
	eval "exec touch $filelist1"
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist1] {}

    runtest 2.1 {
	catch {exec touch /mnt/ABC} error
	set error
    } {touch: /mnt/ABC: File exists}

    set filelist1 [concat $filelist1 $filelist2]

    runtest 2.2 {
	global filelist2
	eval "exec touch $filelist2"
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist1] {}

    puts "  Testing that correct shortnames for longnames were generated"
    puts "  In 2.1.x where x > 74, this should fail as the algorithm changed"
    mountm
    runtest 2.3 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdef~1 /mnt/abcdef~2 /mnt/abcdef~3 /mnt/abcdef~4 /mnt/abcdef~5 /mnt/abcdef~6 /mnt/abcdef~7 /mnt/abcdef~8 /mnt/abcdef~9 /mnt/abcde~10 /mnt/abcde~11 /mnt/abcde~12 /mnt/abcde~13 /mnt/abcde~14 /mnt/abcde~15 /mnt/abcde~16 /mnt/abcde~17 /mnt/abcde~18 /mnt/b /mnt/bc /mnt/bcd /mnt/bcde /mnt/bcdef /mnt/bcdefg /mnt/bcdefgh /mnt/bcdefghi /mnt/bcdefg~1 /mnt/bcdefg~2 /mnt/bcdefg~3 /mnt/bcdefg~4 /mnt/bcdefg~5 /mnt/bcdefg~6 /mnt/bcdefg~7 /mnt/bcdefg~8 /mnt/bcdefg~9 /mnt/bcdef~10 /mnt/bcdef~11 /mnt/bcdef~12 /mnt/bcdef~13 /mnt/bcdef~14 /mnt/bcdef~15 /mnt/bcdef~16 /mnt/bcdef~17}] {}

    puts "  Testing deleting of longnames"
    mountx
    set filelist [lsort [glob -nocomplain /mnt/*]]
    set index [lsearch -exact $filelist /mnt/abcdefghijklm]
    set filelist [lreplace $filelist $index $index]
    runtest 2.4 {
	catch {exec rm /mnt/abcdefghijklm}
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist] {}

    puts "  Testing renaming of longnames"
    set index [lsearch -exact $filelist /mnt/abcdefghijkl]
    set filelist [lreplace $filelist $index $index]
    lappend filelist /mnt/another_long_filename
    runtest 2.5 {
	catch {exec mv /mnt/abcdefghijkl /mnt/another_long_filename}
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist] {}

    puts "  Testing removal of longname by using shortname"
    set index [lsearch -exact $filelist /mnt/abcdefghijklmn]
    set filelist [lreplace $filelist $index $index]
    runtest 2.6 {
	catch {exec rm /mnt/abcdef~6}
	lsort [glob -nocomplain /mnt/*]
    } [lsort $filelist] {}

    mountx
    erasedisk
    puts "  Testing long filenames that have had problems in the past"
    runtest 3.0 {
	catch {exec touch /mnt/athena.tar.gz /mnt/athenaa.tar.gz /mnt/athenaaa.tar.gz /mnt/.depend {/mnt/test.t;x} {/mnt/.pqr .txt} {/mnt/.pqr;.txt} {/mnt/.pqr;;.txt}}
	lsort [glob -nocomplain /mnt/* /mnt/.depend /mnt/.pq*]
    } [lsort {/mnt/athena.tar.gz /mnt/athenaa.tar.gz /mnt/athenaaa.tar.gz {/mnt/test.t;x} /mnt/.depend {/mnt/.pqr .txt} {/mnt/.pqr;.txt} {/mnt/.pqr;;.txt}}] {}

    erasedisk
    runtest 3.1 {
	catch {exec mkdir "/mnt/Program Files"}
	lsort [glob -nocomplain /mnt/*]
    } {{/mnt/Program Files}}

    runtest 3.2 {
	catch {exec mkdir "/mnt/Program Files/plus!"}
	lsort [glob -nocomplain "/mnt/Program Files/*"]
    } {{/mnt/Program Files/plus!}}

    runtest 3.3 {
	catch {exec mkdir "/mnt/Program Files/plus!/Microsoft Internet"}
	lsort [glob -nocomplain "/mnt/Program Files/plus!/*"]
    } {{/mnt/Program Files/plus!/Microsoft Internet}}

    runtest 3.4 {
	catch {exec mkdir "/mnt/Program Files/plus!/Microsoft Internet/cache"}
	lsort [glob -nocomplain "/mnt/Program Files/plus!/Microsoft Internet/*"]
    } {{/mnt/Program Files/plus!/Microsoft Internet/cache}}

    runtest 3.5 {
	catch {exec mkdir "/mnt/Program Files/plus!/Microsoft Internet/cache/bar (1).gif"}
	lsort [glob -nocomplain "/mnt/Program Files/plus!/Microsoft Internet/cache/*"]
    } [lsort {{/mnt/Program Files/plus!/Microsoft Internet/cache/bar (1).gif}}] {}

    erasedisk
    
    puts "  Testing directory creation and . and .. links"
    runtest 3.6 {
        catch {exec mkdir /mnt/flat /mnt/flat/tire /mnt/flat/tire/spoke}
	cd /mnt/flat
	lsort [glob -nocomplain ../*]
    } ../flat {}

    runtest 3.7 {
	lsort [glob -nocomplain ./*]
    } ./tire {}

    runtest 3.8 {
	cd tire
	lsort [glob -nocomplain ../*]
    } ../tire {}

    runtest 3.9 {
        lsort [glob -nocomplain ./*]
    } ./spoke {}

    runtest 3.10 {
	cd spoke
	lsort [glob -nocomplain ../*]
    } ../spoke {}

    runtest 3.11 {
	lsort [glob -nocomplain ./*]
    } {}

    puts "  Testing that directories cannot be moved underneath themselves"
    cd /mnt
    erasedisk
    runtest 3.12 {
	catch {exec mkdir "Program Files"}
	lsort [glob -nocomplain ./*]
    } {{./Program Files}}

    runtest 3.13 {
	catch {exec mv "Program Files" "Program Files"} error
	set error
    } {mv: cannot move `Program Files' to `Program Files/Program Files': Invalid argument}

    runtest 3.14 {
	file isdirectory "Program Files"
    } 1 {}

    runtest 3.15 {
	catch {exec mkdir "Program Files/A Subdirectory"}
	lsort [glob -nocomplain "./Program Files/*"]
    } {{./Program Files/A Subdirectory}}

    runtest 3.16 {
	catch {exec mv "Program Files" "Program Files/A Subdirectory"}
	lsort [glob -nocomplain ./*]
    } {{./Program Files}}

    runtest 3.17 {
	file isdirectory "Program Files"
    } 1 {}

    puts "  Testing that non-empty directories cannot be removed"
    cd /mnt
    erasedisk
    runtest 3.18 {
	lsort [glob -nocomplain ./* ./testing/*]
    } {}
    runtest 3.19 {
	catch {exec mkdir "testing"}
	catch {exec mkdir "testing/a"}
	lsort [glob -nocomplain ./* ./testing/*]
    } [lsort {./testing ./testing/a}] {}

    runtest 3.20 {
	catch {exec rmdir testing} err
	set err
    } {rmdir: testing: Directory not empty}

    puts "  Testing directory renaming"
    runtest 3.21 {
	catch {exec mkdir t}
	catch {exec mv t t1}
	glob -nocomplain ./t1/.*
    } {./t1/. ./t1/..}

    runtest 3.22 {
	catch {exec mkdir t1/testdir1}
	catch {exec mv t1 t2}
	glob -nocomplain ./t2/.* ./t2/*
    } {./t2/. ./t2/.. ./t2/testdir1}

    cd /;
    erasedisk
    mountx

    puts "  Testing directory caching"
    runtest 4.0 {
        exec touch /mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk
        lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}] {}

    mountx
    runtest 4.1 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}] {}

    runtest 4.2 {
	catch {exec rm /mnt/test /mnt/test.ext}
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}] {}

    mountx
    runtest 4.3 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}] {}

    mountx
    erasedisk
    runtest 4.4 {
	lsort [glob -nocomplain /mnt/*]
    } {}

    runtest 4.5 {
	catch {exec touch /mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}
	lsort [glob -nocomplain /mnt/*]
    } [lsort {/mnt/test /mnt/test.ext /mnt/test1234.tst /mnt/a /mnt/ab /mnt/abc /mnt/abcd /mnt/abcde /mnt/abcdef /mnt/abcdefg /mnt/abcdefgh /mnt/abcdefgh.i /mnt/abcdefgh.ij /mnt/abcdefgh.ijk}] {}

    erasedisk
    runtest 4.6 {
	lsort [glob -nocomplain /mnt/*]
    } {}

    runtest 4.6 {
	catch {exec mkdir /mnt/testdir}
	lsort [glob -nocomplain /mnt/*]
    } /mnt/testdir {}

    runtest 4.7 {
	catch {exec touch /mnt/testdir/file1 /mnt/testdir/file2}
	lsort [glob -nocomplain /mnt/testdir/*]
    } {/mnt/testdir/file1 /mnt/testdir/file2}

    runtest 4.8 {
	catch {exec rm -fr /mnt/testdir}
	lsort [glob -nocomplain /mnt/*]
    } {}

    runtest 4.9 {
	catch {exec mkdir /mnt/testdir}
	lsort [glob -nocomplain /mnt/*]
    } /mnt/testdir {}

    runtest 4.10 {
	lsort [glob -nocomplain /mnt/testdir/*]
    } {}

    runtest 4.11 {
	catch {exec touch /mnt/testdir/file /mnt/testdir/another}
	lsort [glob -nocomplain /mnt/testdir/*]
    } [lsort {/mnt/testdir/file /mnt/testdir/another}] {}

    runtest 4.12 {
	catch {exec mv /mnt/testdir/file /mnt/testdir/diffname}
	lsort [glob -nocomplain /mnt/testdir/*]
    } [lsort {/mnt/testdir/another /mnt/testdir/diffname}] {}

    runtest 4.13 {
	lsort [glob -nocomplain /mnt/testdir/file]
    } {}

    puts "  Testing mount options"
    erasedisk
    mountx posix
    runtest 5.0 {
	catch {exec touch /mnt/LongFileName /mnt/longfilename}
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/LongFileName /mnt/longfilename}
    erasedisk

    # This test won't yet succeed
    # runtest 5.1 {
    #	catch {exec touch /mnt/test /mnt/Test /mnt/file1 /mnt/FILE1}
    #	lsort [glob -nocomplain /mnt/*]
    # } { /mnt/FILE1 /mnt/LongFileName /mnt/Test /mnt/file1 /mnt/longfilename /mnt/test}

    mountx nonumtail
    runtest 5.2 {
	catch {exec touch /mnt/longfilename.txt /mnt/longfilename1.txt}
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/longfilename.txt /mnt/longfilename1.txt}

    mountm
    runtest 5.3 {
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/longfile.txt /mnt/longfi~1.txt}

    mountx uid=62531
    runtest 5.4 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfilename1.txt var} err] {
	    set err
	} else {
	    set var(uid)
	}
    } 62531

    mountx gid=62532
    runtest 5.5 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfilename1.txt var} err] {
	    set err
	} else {
	    set var(gid)
	}
    } 62532

    mountm uid=62533
    runtest 5.6 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfile.txt var} err] {
	    set err
	} else {
	    set var(uid)
	}
    } 62533

    mountm gid=62534
    runtest 5.7 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfile.txt var} err] {
	    set err
	} else {
	    set var(gid)
	}
    } 62534

    mountx uid=62531,gid=62532
    runtest 5.8 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfilename1.txt var} err] {
	    set err
	} else {
	    list $var(uid) $var(gid)
	}
    } {62531 62532}

    mountx nonumtail,uid=62531,gid=62532
    runtest 5.9 {
	if [info exists var] { unset var }
	if [catch {file stat /mnt/longfilename1.txt var} err] {
	    set err
	} else {
	    list $var(uid) $var(gid)
	}
    } {62531 62532}

    erasedisk
    runtest 5.10 {
	catch {exec touch /mnt/LongFileNameTest /mnt/LongFileNameTest1}
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/LongFileNameTest /mnt/LongFileNameTest1}

    mountm
    runtest 5.11 {
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/longfile /mnt/longfi~1}


    mountx uni_xlate
    erasedisk
    runtest 5.12 {
	catch {exec touch /mnt/fil:4G4:444:4G4 /mnt/toc:3q4:104}
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/fil:4G4:444:4G4 /mnt/toc:3q4:104}

    mountx
    runtest 5.13 {
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/fil??? /mnt/toc??}

    mountx gid=62532,uni_xlate
    runtest 5.14 {
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/fil:4G4:444:4G4 /mnt/toc:3q4:104}

    mountx uni_xlate,gid=62532
    runtest 5.15 {
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/fil:4G4:444:4G4 /mnt/toc:3q4:104}

    erasedisk
    mountx iocharset=iso8859-1
    runtest 5.16 {
	catch {exec touch "/mnt/Long luft" "/mnt/luft"}
	catch {exec touch "/mnt/Long natrlich"}
	lsort [glob -nocomplain /mnt/*]
    } [lsort {{/mnt/Long luft} {/mnt/Long natrlich} /mnt/luft}] {}

    mountx utf8
    runtest 5.17 {
	lsort [glob -nocomplain /mnt/*]
    } [lsort {{/mnt/Long läuft} {/mnt/Long natürlich} /mnt/luft}]


}
    puts "  Checking how well open files deal with moving and being deleted"

    # Check that files can be moved while they are still open

    mountx debug
    erasedisk
    runtest 6.0 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/testfile w]
	    puts $f before
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/testfile /mnt/testfile
	    puts $f after
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testfile r]
	    gets $f line1
	    gets $f line2
	    close $f
	    list $line1 $line2
	} out
	set out
    } {before after}

    # Single move with writing to alias and longname
    mountx debug
    erasedisk
    runtest 6.0.1 {
	catch {
	    set f1 [open /mnt/LongFileName w]
	    set f2 [open /mnt/longfi~1 w]
	    seek $f1 0 end; puts $f1 realbefore; flush $f1
	    seek $f2 0 end; puts $f2 aliasbefore; flush $f2
	    exec sync
	    exec mv /mnt/LongFileName /mnt/TestFileName
	    seek $f1 0 end; puts $f1 realafter; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter; flush $f2
	    exec sync
	    close $f1
	    close $f2
	    set f [open /mnt/TestFileName r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    gets $f line4
	    close $f
	    list $line1 $line2 $line3 $line4
	} out
	set out
    } {realbefore aliasbefore realafter aliasafter}

    # Single move with writing to alias and longname
    mountx debug
    erasedisk
    runtest 6.0.2 {
	catch {
	    set f1 [open /mnt/LongFileName w]
	    set f2 [open /mnt/longfi~1 w]
	    seek $f1 0 end; puts $f1 realbefore1; flush $f1
	    seek $f2 0 end; puts $f2 aliasbefore1; flush $f2
	    exec sync
	    exec mv /mnt/LongFileName /mnt/TestFileName
	    seek $f1 0 end; puts $f1 realafter1; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter1; flush $f2
	    close $f1
	    close $f2
	    set f [open /mnt/TestFileName r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    gets $f line4
	    close $f
	    list $line1 $line2 $line3 $line4
	} out
	set out
    } {realbefore1 aliasbefore1 realafter1 aliasafter1}

    # Double move with writing to alias and longname
    mountx debug
    erasedisk
    runtest 6.0.3 {
	catch {
	    set f1 [open /mnt/LongFileName w]
	    set f2 [open /mnt/longfi~1 w]
	    seek $f1 0 end; puts $f1 realbefore1; flush $f1
	    seek $f2 0 end; puts $f2 aliasbefore1; flush $f2
	    exec sync
	    exec mv /mnt/LongFileName /mnt/TestFileName
	    seek $f1 0 end; puts $f1 realafter1; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter1; flush $f2
	    exec sync
	    exec mv /mnt/TestFileName /mnt/TestName2
	    seek $f1 0 end; puts $f1 realafter2; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter2; flush $f2
	    close $f1
	    close $f2
	    set f [open /mnt/TestName2 r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    gets $f line4
	    gets $f line5
	    gets $f line6
	    close $f
	    list $line1 $line2 $line3 $line4 $line5 $line6
	} out
	set out
    } {realbefore1 aliasbefore1 realafter1 aliasafter1 realafter2 aliasafter2}

    # Double move with writing to alias and longname.  On second move,
    # file is renamed back to original name
    runtest 6.0.4 {
	catch {
	    set f1 [open /mnt/LongFileName w]
	    set f2 [open /mnt/longfi~1 w]
	    seek $f1 0 end; puts $f1 realbefore1; flush $f1
	    seek $f2 0 end; puts $f2 aliasbefore1; flush $f2
	    exec sync
	    exec mv /mnt/LongFileName /mnt/TestFileName
	    seek $f1 0 end; puts $f1 realafter1; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter1; flush $f2
	    exec sync
	    exec mv /mnt/TestFileName /mnt/LongFileName
	    seek $f1 0 end; puts $f1 realafter2; flush $f1
	    seek $f2 0 end; puts $f2 aliasafter2; flush $f2
	    close $f1
	    close $f2
	    set f [open /mnt/LongFileName r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    gets $f line4
	    gets $f line5
	    gets $f line6
	    close $f
	    list $line1 $line2 $line3 $line4 $line5 $line6
	} out
	set out
    } {realbefore1 aliasbefore1 realafter1 aliasafter1 realafter2 aliasafter2}

    runtest 6.0.5 {
	catch {
	    set f [open /mnt/a w]
	    puts $f before
	    close $f
	    exec mv /mnt/a /mnt/b

	    set f [open /mnt/b r]
	    gets $f line1
	    close $f
	    list $line1
	} out
	set out
    } {before}

    # Check that files can be moved while they are still open
    erasedisk
    runtest 6.1 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/testfile w]
	    puts $f before
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/testfile /mnt/testfile
	    puts $f move1
	    flush $f
	    exec sync
	    exec mv /mnt/testfile /mnt/testfile.1
	    puts $f move2
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testfile.1 r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    close $f
	    list $line1 $line2 $line3
	} out
	set out
    } {before move1 move2}

    # Check what happens when a file that is open is replaced with
    # another file
    erasedisk
    runtest 6.2 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/file1 w]
	    puts $f "test file1"
	    close $f
	    set f [open /mnt/testdir/file2 w]
	    puts $f "before"
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/file1 /mnt/testdir/file2
	    puts $f "after"
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testdir/file2 r]
	    gets $f line1
	    close $f
	    list $line1
	} out
	set out
    } {{test file1}}

    # Check that an open file can be deleted with no harmful side effects
    erasedisk
    runtest 6.3 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/file w]
	    puts $f before
	    flush $f
	    exec sync
	    exec rm -f /mnt/testdir/file
	    puts $f after
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testdir/file r]
	} out
	set out
    } {couldn't open "/mnt/testdir/file": no such file or directory}

    erasedisk
    runtest 6.4 {
	catch {
	    set f [open /mnt/a w]
	    puts $f "0123456789ABCDEF"
	    close $f
	    exec mv /mnt/a /mnt/b
	    set f [open /mnt/b r]
	    gets $f line1
	    close $f
	    set line1
	} out
	set out
    } {0123456789ABCDEF}

    # Check that files can be moved while they are still open on msdosfs
    mountm
    erasedisk
    runtest 6.5 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/testfile w]
	    puts $f before
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/testfile /mnt/testfile
	    puts $f after
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testfile r]
	    gets $f line1
	    gets $f line2
	    close $f
	    list $line1 $line2
	} out
	set out
    } {before after}

    # Check that files can be moved while they are still open
    erasedisk
    runtest 6.6 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/testfile w]
	    puts $f before
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/testfile /mnt/testfile
	    puts $f move1
	    flush $f
	    exec sync
	    exec mv /mnt/testfile /mnt/testfile.1
	    puts $f move2
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testfile.1 r]
	    gets $f line1
	    gets $f line2
	    gets $f line3
	    close $f
	    list $line1 $line2 $line3
	} out
	set out
    } {before move1 move2}

    # Check what happens when a file that is open is replaced with
    # another file
    erasedisk
    runtest 6.7 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/file1 w]
	    puts $f "test file1"
	    close $f
	    set f [open /mnt/testdir/file2 w]
	    puts $f before
	    flush $f
	    exec sync
	    exec mv /mnt/testdir/file1 /mnt/testdir/file2
	    puts $f after
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testdir/file2 r]
	    gets $f line1
	    close $f
	    list $line1
	} out
	set out
    } {{test file1}}

    # Check that an open file can be deleted with no harmful side effects
    erasedisk
    runtest 6.8 {
	catch {
	    exec mkdir /mnt/testdir
	    set f [open /mnt/testdir/file w]
	    puts $f before
	    flush $f
	    exec sync
	    exec rm -f /mnt/testdir/file
	    puts $f after
	    flush $f
	    exec sync
	    close $f
	    set f [open /mnt/testdir/file r]
	} out
	set out
    } {couldn't open "/mnt/testdir/file": no such file or directory}

    erasedisk
    runtest 6.9 {
	catch {
	    set f [open /mnt/a w]
	    puts $f "0123456789ABCDEF"
	    close $f
	    exec mv /mnt/a /mnt/b
	    set f [open /mnt/b r]
	    gets $f line1
	    close $f
	    set line1
	} out
	set out
    } {0123456789ABCDEF}

    mountx
    erasedisk
    puts "  Checking reserved filename handling"
    runtest 7.0 {
	catch {exec touch /mnt/aux}
	catch {exec touch /mnt/com0 /mnt/com10}
	catch {exec touch /mnt/com1}
	catch {exec touch /mnt/cOm1}
	catch {exec touch /mnt/cOm1.longfilename}
	catch {exec touch /mnt/com1.x}
	catch {exec touch /mnt/com1.longfilename}
	lsort [glob -nocomplain /mnt/*]
    } {/mnt/com0 /mnt/com10}

    mountx
    erasedisk
    puts "  Checking dcache handling"

    runtest 8.0 {
	catch {exec touch /mnt/LongFileName}
	glob -nocomplain /mnt/LongFileName.
    } /mnt/LongFileName. {}

    runtest 8.1 {
	glob -nocomplain /mnt/LongFileName..
    } /mnt/LongFileName.. {}

    runtest 8.2 {
	glob -nocomplain /mnt/LongFileName...
    } /mnt/LongFileName... {}

    runtest 8.3 {
	catch {exec rm -f /mnt/LongFileName....}
	glob -nocomplain /mnt/LongFileName
    } {}

    runtest 8.4 {
	glob -nocomplain /mnt/LongFileName.
    } {}

    runtest 8.5 {
	catch {exec rm -f /mnt/LongFileName....}
	glob -nocomplain /mnt/LongFileName..
    } {}

    runtest 8.6 {
	catch {exec rm -f /mnt/LongFileName....}
	glob -nocomplain /mnt/LongFileName...
    } {}

    runtest 8.7 {
	catch {exec touch /mnt/LongFileName}
	glob -nocomplain /mnt/LongFileName
    } /mnt/LongFileName {}

    runtest 8.8 {
	glob -nocomplain /mnt/longfi~1
    } /mnt/longfi~1 {}

    # Some of these tests will currently fail, but it the fs needs to be made to work
    runtest 8.9 {
	catch {exec rm -f /mnt/longfi~1}
	glob -nocomplain /mnt/LongFileName
    } {}

    runtest 8.10 {
	glob -nocomplain /mnt/...
    } {}

    runtest 8.11 {
	glob -nocomplain /mnt/DoesNotExistYet
    } {}
    runtest 8.12 {
	glob -nocomplain /mnt/doesno~1
    } {}
    runtest 8.13 {
	catch {exec touch /mnt/DoesNotExistYet}
	glob -nocomplain /mnt/DoesNotExistYet
    } /mnt/DoesNotExistYet {}
    runtest 8.14 {
	catch {exec touch /mnt/doesno~1}
	glob -nocomplain /mnt/doesno~1
    } /mnt/doesno~1 {}
    runtest 8.15 {
	catch {exec rm -f /mnt/DoesNotExistYet}
	glob -nocomplain /mnt/doesno~1
    } {}

    mountx
    erasedisk
    set check 0
    if [file isdirectory /usr/src/linux/drivers/sound] {
	puts "  Tarring up portions of the kernel tree and untarring on vfat"

	if [catch {
	    cd /usr/src/linux/drivers
	    catch {exec tar cvf /tmp/sound.tar sound}

	    if [file isfile /tmp/sound.tar] {
		cd /mnt;
		catch {exec tar xvf /tmp/sound.tar}
		set check 1
	    }
	} error] {
	    global errorInfo
	    puts "  Error: $error $errorInfo"
	}
	catch {exec rm -f /tmp/sound.tar}
    }
    if {$check} {
	puts "  Checking for differences between /usr/src/linux/drivers/sound/ and /mnt/"
	dirRecurseCheck /usr/src/linux/drivers/sound/ /mnt/sound/
    }
    cd /
}
