-
Notifications
You must be signed in to change notification settings - Fork 2
/
bitrock-unpacker.tcl
executable file
·119 lines (94 loc) · 3.08 KB
/
bitrock-unpacker.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env tclkit
#
# Bitrock unpacking script
# Author : mickael9 <mickael9 at gmail dot com>
source /usr/bin/sdx.kit
if {$argc < 2} {
puts "Usage: $argv0 installerFile outputDirectory"
exit 1
}
set installerFile [lindex $argv 0]
set destDir [lindex $argv 1]
set installerMount /installer
set dataMount /installerData
vfs::mk4::Mount $installerFile $installerMount -readonly
lappend auto_path $installerMount/libraries/
package require vfs::cookfs
package require Tcllzmadec
# progress from http://wiki.tcl.tk/16939 (sligtly modified)
# thanks to the author
proc progress {cur tot} {
# set to total width of progress bar
set total 76
if {$cur == $tot} {
# cleanup
set str "\r[string repeat " " [expr $total + 4]]\r"
} else {
set half [expr {$total/2}]
set percent [expr {100.*$cur/$tot}]
set val (\ [format "%6.2f%%" $percent]\ )
set str "\r|[string repeat = [
expr {round($percent*$total/100)}]][
string repeat { } [expr {$total-round($percent*$total/100)}]]|"
set str "[string range $str 0 $half]$val[string range $str [expr {$half+[string length $val]-1}] end]"
}
puts -nonewline stderr $str
}
# Read cookfs options
set optionsFile [open $installerMount/cookfsinfo.txt]
set options [read $optionsFile]
close $optionsFile
# Read the manifest
set manifestFile [open $installerMount/manifest.txt]
set manifest [read $manifestFile]
close $manifestFile
# Mount the files to $dataMount
vfs::cookfs::Mount {*}$options $installerFile $dataMount
puts "Creating directories..."
foreach {fileName props} $manifest {
set type [lindex $props 0]
if {$type == "directory"} {
set mode [lindex $props 1]
file mkdir $destDir/$fileName
}
}
puts "Unpacking files, please wait..."
set entryCount [expr [llength $manifest] / 2]
set entryIndex 0
foreach {fileName props} $manifest {
set type [lindex $props 0]
if {$type == "file"} {
set mode [lindex $props 1]
set sizes [lindex $props 4]
set nparts [llength $sizes]
set index 1
file mkdir [file dirname $destDir/$fileName]
file copy -force $dataMount/$fileName $destDir/$fileName
if {$nparts > 0} {
set fp [open $destDir/$fileName a]
fconfigure $fp -translation binary
while {$index < $nparts} {
set chunkName $dataMount/${fileName}___bitrockBigFile$index
set fp2 [open $chunkName r]
fconfigure $fp2 -translation binary
puts -nonewline $fp [read $fp2]
close $fp2
incr index
}
close $fp
}
file attributes $destDir/$fileName -permissions $mode
}
incr entryIndex
progress $entryIndex $entryCount
}
puts "Creating links..."
foreach {fileName props} $manifest {
set type [lindex $props 0]
if {$type == "link"} {
set linkTarget [lindex $props 1]
file delete $destDir/$fileName
file link -symbolic $destDir/$fileName $linkTarget
}
}
puts "Done"