Skip to content

Instantly share code, notes, and snippets.

@NyaMisty
Forked from zhangyoufu/extract-installbuilder.tcl
Last active September 3, 2023 11:11

Revisions

  1. NyaMisty revised this gist Jan 11, 2022. 1 changed file with 0 additions and 0 deletions.
    Binary file added tclkit-21.9.0
    Binary file not shown.
  2. @zhangyoufu zhangyoufu created this gist Aug 10, 2020.
    120 changes: 120 additions & 0 deletions extract-installbuilder.tcl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,120 @@
    #!./tclkit

    ## prepare runtime environment
    proc init {} {
    ## mount optional.pak (for tcltwofish)
    set optionalPak installbuilder/paks/optional.pak
    vfs::mk4::Mount $optionalPak $optionalPak -readonly

    ## adjust library search path
    set ::auto_path [list $tcl::kitpath/lib/tcl$::tcl_version $tcl::kitpath/lib $tcl::kitpath/libraries $optionalPak/linux-x64 $tcl::kitpath]

    ## load packages
    package require maui::util
    package require vfs::cookfs
    }

    proc extract_metakit {src dst} {
    ## mount metakit
    set db [tclKitMkOpen $src]
    vfs::filesystem mount $src [list vfs::mk4::handler $db]
    vfs::RegisterMount $src [list vfs::mk4::Unmount $db]

    ## ensure destination directory
    file mkdir $dst

    ## read cookfsinfo.txt
    set f [open $src/cookfsinfo.txt]
    gets $f cookfsinfo
    close $f

    ## read manifest.txt
    set f [open $src/manifest.txt]
    set manifest [read $f]
    close $f

    ## copy project.xml
    file copy -- $src/project.xml $dst

    ## copy images/
    file copy -- $src/images $dst

    ## unmount metakit
    vfs::filesystem unmount $src

    return [list $cookfsinfo $manifest]
    }

    proc extract {src password dst} {
    ## clean up destination
    file delete -force $dst

    ## copy images/ to dst, get manifest, mount cookfs
    lassign [extract_metakit $src $dst] cookfsinfo manifest

    ## mount cookfs
    set cookfsHandle [vfs::cookfs::Mount $src $src -readonly {*}$cookfsinfo]

    ## prepare decryption
    set payloadinfo [$cookfsHandle getmetadata "installbuilder.payloadinfo"]
    maui::util::m4ZQu $password $payloadinfo

    ## copy cookfs content to components/
    set dst $dst/components

    ## extract directory/file/link
    foreach {fileName props} $manifest {
    puts "$fileName"

    # directory mode mtime 0 {0 0}
    # file mode mtime 0 {{0 size} {0 size}}
    # link target mtime {0 0}
    lassign $props type arg mtime
    switch -- $type {
    directory {
    file mkdir $dst/$fileName
    file attributes $dst/$fileName -permissions $arg
    }
    file {
    file mkdir [file dirname $dst/$fileName]
    file copy $src/$fileName $dst/$fileName
    set numParts [llength [lindex $props 4]]
    if {$numParts > 0} {
    set fdst [open $dst/$fileName {WRONLY APPEND BINARY}]
    for {set i 1} {$i < $numParts} {incr i} {
    set fsrc [open $src/${fileName}___bitrockBigFile$i {RDONLY BINARY}]
    fcopy $fsrc $fdst
    close $fsrc
    }
    close $fdst
    }
    file attributes $dst/$fileName -permissions $arg
    file mtime $dst/$fileName $mtime
    }
    link {
    file mkdir [file dirname $dst/$fileName]
    # file link -symbolic $dst/$fileName $arg
    # file mtime $dst/$fileName $mtime
    exec ln -s -- $arg $dst/$fileName
    exec touch -h -t [clock format $mtime -format %Y%m%d%H%M.%S] $dst/$fileName
    }
    default {
    error "not implemented"
    }
    }
    }

    ## restore directory mtime
    foreach {fileName props} $manifest {
    lassign $props type arg mtime
    if {$type == "directory"} {
    file mtime $dst/$fileName $mtime
    }
    }

    ## unmount cookfs
    vfs::filesystem unmount $src
    }

    init
    extract {*}$argv
    4 changes: 4 additions & 0 deletions get-tclkit.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    #!/bin/sh
    cp installbuilder/paks/linux-x64-noupx.pak tclkit
    sed --in-place --null-data --expression='/^if {\[file isfile \[file join \$::tcl::kitpath main.tcl/{s/^./\x1A/}' tclkit
    chmod +x tclkit