proc die {reason} {
global argv0
puts stderr "$argv0: fatal: $reason"
exit -2
}
proc nextrec {fd} {
set hdr [read $fd 512]
binary scan $hdr c _
if {[string length $hdr] != 512} { die "got partial header: [string length $hdr]b" }
binary scan $hdr a100c24a11c1c12c8a1c* name blind1 size _ blind2 _ type blind3
set name [lindex [split $name "\0"] 0]
if {$name == {}} return
set data [read $fd [expr {$size}]]
if {$size % 512 != 0} {
read $fd [expr {512 - ($size % 512)}]
}
return [list name $name type $type data [binary encode hex $data] blind1 $blind1 blind2 $blind2 blind3 $blind3]
}
proc putrec {fd rec} {
set name [dict get $rec name]
set type [dict get $rec type]
set size [expr {[string length [dict get $rec data]] / 2}]
set size [format %011o $size]
# puts "$name - $size"
set blind1 [dict get $rec blind1]
set blind2 [dict get $rec blind2]
set blind3 [dict get $rec blind3]
set hdr [binary format a100c24a12c12A8a1c* $name $blind1 $size $blind2 "" $type $blind3]
binary scan $hdr c* bytes
set checksum 0
foreach byte $bytes {
incr checksum [expr {$byte & 0xFF}]
}
set checksum [format %07o $checksum]
set hdr [binary format a100c24a12c12a8a1c* $name $blind1 $size $blind2 $checksum $type $blind3]
puts -nonewline $fd $hdr
puts -nonewline $fd [binary decode hex [dict get $rec data]]
if {$size % 512 != 0} {
puts -nonewline $fd [binary format a[expr {512 - ($size % 512)}] ""]
}
}
set fd [open [lindex $argv 0] rb]
set fd2 [open [lindex $argv 1] wb]
while {[set record [nextrec $fd]] != {}} {
if {[dict get $record type] == "0"} {
puts "type of [dict get $record name] is 0, overwriting"
dict set record data [binary encode hex "Hello, World!"]
# puts $record
}
putrec $fd2 $record
}
puts -nonewline $fd2 [binary format a[expr {16384 - ([tell $fd2] % 16384)}] ""]