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