#! /home/jcw/bin/tclkit # This cgi script gets called for all requests in the get/ directory. # It expects to be called with an url such as: # https://www.equi4.com/starch/get/3dmaze.kit # https://www.equi4.com/starch/get/3dmaze-12345-23456.kit # Such urls are listed in the "listing.html" output of "listall.tcl". # The returned result is an on-the-fly (re-)constructed starkit. # # TODO: # - construct zip files on the fly too, using critlib's "zipper" package # (it's not hard, it could even be done for tar.gz's with a bit more work) # - optimize this (cache generated files?), it's way too slow for big sk's # (note that creating "get/U9..8B/3dmaze.kit" would automatically cache it) # # jcw, 2003-09-04 if {[catch { source [file join [file dirname [info script]] util.tcl] set start [clock clicks -milli] # requests have a very strict format if {![regexp {get/(.{31})(.*)/(.+)\.(...)$} $env(REQUEST_URI) - a1 a2 b e]} { error "can't parse request URL" } # but there are two variants, i.e. either "tailmd" or "tailmd,headmd" if {![regexp {^,(.{31})$} $a2 - a2]} { set a2 K9RL3ARM1PEMIMLTD35LFO6D9K00080 ;# default 256-byte starkit header } if {$e eq "kit"} { # get the head, i.e. the data preceding the MK data set head [readone $a2] catch { set head [vfs::zip -mode decompress $head] } } else { # other file formats don't use header set head "" error "file type '$e' not currently supported" ;# TODO } # get the tail, i.e. the MK data portion set tail [readone $a1] catch { set tail [vfs::zip -mode decompress $tail] } # load tail string into a MK in-mem db, via memchan stream set fd [vfs::memchan] fconfigure $fd -translation binary puts -nonewline $fd $tail seek $fd 0 mk::file open db mk::file load db $fd close $fd # restucture catalog to drop the "md5" and add the "contents" property # note that all md5 values are still available *until* commit or close! mk::view layout db.dirs \ {name parent:I {files {name size:I date:I contents:B}}} # go through all entries, loading datafiles for each md5 value set count 0 mk::loop c db.dirs { mk::loop d $c.files { set x [amsname [mk::get $d md5] [mk::get $d size]] mk::set $d contents [readone $x] incr count } } # append a log entry with some statistics, if possible catch { set finish [clock clicks -milli] set fd [open /home/jcw/data/sgetlog.txt a] set t [clock format [clock seconds] -format {%Y/%m/%d %H:%M:%S} -gmt 1] puts $fd "$t [list [expr {($finish-$start)/1000.0}]s ${count}f \ $env(REMOTE_ADDR) $env(REQUEST_URI)]" close $fd } # done, return the resulting starkit puts "Content-type: application/octet-stream" puts "" fconfigure stdout -translation binary puts -nonewline $head mk::file save db stdout mk::file close db }]} { # error handling: present error message as html output puts "Content-type: text/html" puts "" puts
parray env puts "" puts $errorInfo puts}