1#! /usr/bin/env tclkit 2 3# Re-pack a starkit/starpack or MK datafile (header is kept intact) 4# Jan 2004, jcw@equi4.com 5 6proc fail {msg} { puts stderr "${::inf}: $msg"; exit 1 } 7 8if {[llength $argv] != 2} { 9 set inf usage 10 fail "$argv0 infile outfile" 11} 12 13set inf [lindex $argv 0] 14set ouf [lindex $argv 1] 15 16if {[file normalize $inf] eq [file normalize $ouf]} { 17 fail "input and output may not be the same file" 18} 19if {![file exists $inf]} { 20 fail "file does not exist" 21} 22if {![file isfile $inf]} { 23 fail "this is not a regular file (perhaps mounted as VFS?)" 24} 25set end [file size $inf] 26if {$end < 27} { 27 fail "file too small, cannot be a datafile" 28} 29 30set fd [open $inf] 31fconfigure $fd -translation binary 32seek $fd -16 end 33binary scan [read $fd 16] IIII a b c d 34 35#puts [format %x-%d-%x-%d $a $b $c $d] 36 37if {($c >> 24) != -128} { 38 fail "this is not a Metakit datafile" 39} 40 41# avoid negative sign / overflow issues 42if {[format %x [expr {$a & 0xffffffff}]] eq "80000000"} { 43 set start [expr {$end - 16 - $b}] 44} else { 45 # if the file is in commit-progress state, we need to do more 46 fail "this code needs to be finished..." 47} 48 49seek $fd $start 50switch -- [read $fd 2] { 51 JL { set endian little } 52 LJ { set endian big } 53 default { fail "failed to locate data header" } 54} 55seek $fd 0 56 57mk::file open db $inf -readonly 58 59set ofd [open $ouf w] 60fconfigure $ofd -translation binary 61fcopy $fd $ofd -size $start 62mk::file save db $ofd 63close $ofd 64 65puts "$inf: [file size $inf] bytes" 66puts "$ouf: [file size $ouf] bytes" 67 68close $fd 69