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)}] ""]