Index: .fossil-settings/ignore-glob
==================================================================
--- .fossil-settings/ignore-glob
+++ .fossil-settings/ignore-glob
@@ -1,7 +1,10 @@
build/test/kits
build/test/kits/*
+build/web/queue
+build/web/kitcreator.cgi
+build/web/kitcreator.kit
itcl/build
itcl/build/*
itcl/build.log
itcl/inst
itcl/inst/*
@@ -91,10 +94,19 @@
tcc4tcl/inst/*
tcc4tcl/out
tcc4tcl/out/*
tcc4tcl/src
tcc4tcl/src/*
+tls/build
+tls/build/*
+tls/build.log
+tls/inst
+tls/inst/*
+tls/out
+tls/out/*
+tls/src
+tls/src/*
kitdll/buildsrc/kitdll-0.0/starpack.vfs
kitdll/buildsrc/kitdll-0.0/starpack.vfs/*
kitdll/buildsrc/kitdll-0.0/test
kitdll/buildsrc/kitdll-0.0/configure
kitdll/buildsrc/kitdll-0.0/libtcl*.so
Index: build/web/Makefile
==================================================================
--- build/web/Makefile
+++ build/web/Makefile
@@ -1,15 +1,23 @@
STARKIT2EXE = ../../../starkit2exe/starkit2exe
RIVET2STARKIT = ../../../rivet/bin/rivet2starkit
+WEBDIR = /web/customers/kitcreator.rkeene.org
+WEBKITSDIR = $(WEBDIR)/kits
kitcreator.cgi: kitcreator.kit
$(STARKIT2EXE) kitcreator.kit kitcreator.cgi
kitcreator.kit: kitcreator.vfs kitcreator.vfs/index.rvt
$(RIVET2STARKIT) tclkit kitcreator.kit kitcreator.vfs
+install: kitcreator.cgi building.cgi
+ mkdir -p '$(WEBDIR)' '$(WEBKITSDIR)'
+ cp kitcreator.cgi '$(WEBDIR)/'
+ cp building.cgi '$(WEBKITSDIR)/'
+ echo -n > '${WEBKITSDIR}/index.html'
+
clean:
rm -f kitcreator.kit kitcreator.cgi
distclean: clean
-.PHONY: clean distclean
+.PHONY: clean distclean install
ADDED build/web/building.cgi
Index: build/web/building.cgi
==================================================================
--- /dev/null
+++ build/web/building.cgi
@@ -0,0 +1,64 @@
+#! /usr/bin/env tclsh
+
+set outdir "/web/customers/kitcreator.rkeene.org/kits"
+set key ""
+if {[info exists ::env(PATH_INFO)]} {
+ set key [lindex [split $::env(PATH_INFO) "/"] 1]
+}
+
+set status "Unknown"
+set terminal 0
+if {![regexp {^[0-9a-f]+$} $key]} {
+ set status "Invalid Key"
+
+ unset key
+}
+
+if {[info exists key]} {
+ set workdir [file join $outdir $key]
+}
+
+if {[info exists workdir]} {
+ if {[file exists $workdir]} {
+ set fd [open [file join $workdir filename]]
+ set filename [gets $fd]
+ close $fd
+
+ set outfile [file join $workdir $filename]
+ } else {
+ set status "Queued"
+ }
+}
+
+if {[info exists outfile]} {
+ if {[file exists $outfile]} {
+ set status "Complete"
+
+ set url "http://kitcreator.rkeene.org/kits/$key/$filename"
+ } elseif {[file exists "${outfile}.buildfail"]} {
+ set status "Failed"
+
+ set terminal 1
+ } else {
+ set status "Building"
+ }
+}
+
+puts "Content-Type: text/html"
+if {[info exists url]} {
+ puts "Location: $url"
+} else {
+ if {!$terminal} {
+ puts "Refresh: 30;url=."
+ }
+}
+puts ""
+puts ""
+puts "\t
"
+puts "\t\tKitCreator, Web Interface"
+puts "\t"
+puts "\t"
+puts "\t\tKitCreator Web Interface
"
+puts "\t\tStatus: $status
"
+puts "\t"
+puts ""
Index: build/web/kitcreator.vfs/index.rvt
==================================================================
--- build/web/kitcreator.vfs/index.rvt
+++ build/web/kitcreator.vfs/index.rvt
@@ -1,52 +1,245 @@
+ package require sha1
+
+ load_response args
+
set sourcedir "/web/rkeene/devel/kitcreator/all"
+ set queue "/home/rkeene/devel/kitcreator/build/web/queue"
+ set secretfile "/home/rkeene/etc/kitcreator-web-secret"
+
foreach file [glob -tails -nocomplain -directory $sourcedir "kitcreator-*.tar.gz"] {
regexp {^kitcreator-(.*).tar.gz$} $file -> vers
set kitcreator_versions($vers) $vers
}
set kitcreator_version_selected [lindex [lsort -dictionary [array names kitcreator_versions]] end]
set kitcreator_versions(trunk) "Fossil Trunk Tip"
- set tcl_versions(8.4.19) 8.4.19
- set tcl_versions(8.5.9) 8.5.9
- set tcl_versions(cvs_HEAD) "Fossil Trunk Tip"
-
- set platforms(linux-x86) "Linux on x86"
- set platforms(linux-amd64) "Linux on amd64"
- set platforms(linux-mipsel) "Linux on MIPSEL"
- set platforms(windows-x86) "Windows on x86"
+ set tcl_versions(8.5.15) 8.5.15
+ set tcl_versions(8.6.1) 8.6.1
+ set tcl_versions(fossil_trunk) "Fossil Trunk Tip"
+
+ set platforms(android-arm) "Android/ARM"
+ set platforms(freebsd-amd64) "FreeBSD/amd64"
+ set platforms(hpux-hppa64) "HP-UX/PA-RISC 2.0"
+ set platforms(linux-amd64) "Linux/amd64"
+ set platforms(linux-arm) "Linux/ARM"
+ set platforms(linux-i386) "Linux/i386"
+ set platforms(linux-mipsel) "Linux/MIPS"
+ set platforms(netbsd-amd64) "NetBSD/amd64"
+ set platforms(netbsd-i386) "NetBSD/i386"
+ set platforms(solaris-amd64) "Solaris/amd64"
+ set platforms(solaris-i386) "Solaris/i386"
+ set platforms(solaris-sparc) "Solaris/SPARC"
+ set platforms(solaris-sparc64) "Solaris/SPARC64"
+ set platforms(win32) "Windows/i386"
+ set platforms(win64) "Windows/amd64"
+
+ set packages(tk) "Tk"
+ set packages(mk4tcl) "Metakit"
+ set packages(tcc4tcl) "tcc4tcl"
+ set packages(tls) TLS
+ set packages(dbus) D-BUS
+ set packages(tclx) TclX
set disable {
- platform linux-amd64 tk
- platform linux-mipsel tk
+ platform linux-mipsel {tk tcc4tcl}
+ platform android-arm tk
+ platform netbsd-amd64 {tk tcc4tcl}
+ platform netbsd-i386 {tk tcc4tcl}
+ platform solaris-sparc tcc4tcl
+ platform solaris-sparc64 tcc4tcl
+ platform hpux-hppa64 tcc4tcl
}
set specific {
- platform windows-x86 file icon {Kit Icon}
- platform windows-x86 text description {Description}
+ platform win32 file icon {Kit Icon}
+ platform win32 text description {Description}
+ platform win64 file icon {Kit Icon}
+ platform win64 text description {Description}
}
+
+ if {[info exists args(platform)] && [info exists args(tcl_version)] && [info exist args(kitcreator_version)]} {
+ # Read in arguments
+ ## Mandatory arguments
+ set build_platform $args(platform)
+ set build_tcl_version $args(tcl_version)
+ set build_kitcreator_version $args(kitcreator_version)
+
+ ## Optional Arguments
+ set build_packages [list]
+ set build_options(threaded) 0
+ set build_options(kitdll) 0
+ foreach arg [array names args] {
+ switch -glob -- $arg {
+ "option_package_*" {
+ set package [join [lrange [split $arg _] 2 end] _]
+
+ lappend build_packages $package
+ }
+ "option_threaded" {
+ set build_options(threaded) 1
+ }
+ "option_kitdll" {
+ set build_options(kitdll) 1
+ }
+ }
+ }
+ set build_packages [lsort -dictionary $build_packages]
+
+ # Validate arguments
+ if {![info exists platforms($build_platform)]} {
+ unset build_platform
+ }
+
+ if {![info exists tcl_versions($build_tcl_version)]} {
+ unset build_tcl_version
+ }
+
+ if {![info exists kitcreator_versions($build_kitcreator_version)]} {
+ unset build_kitcreator_version
+ }
+
+ foreach package $build_packages {
+ if {![info exists packages($package)]} {
+ unset build_packages
+
+ break
+ }
+ }
+
+ # Resolve version numbers to checkin IDs
+ ## XXX: TODO
+ set cache_tcl_version $build_tcl_version
+ if {$build_tcl_version == "fossil_trunk"} {
+ set cache_tcl_version [clock seconds]
+ }
+
+ set cache_kitcreator_version $build_kitcreator_version
+ if {$build_kitcreator_version == "trunk"} {
+ set cache_kitcreator_version [clock seconds]
+ }
+
+ # Generate a serialized hash that represents the state of the build
+ ## Load a secret so keys cannot be pre-computed (but remain consistent)
+ set secretfd [open $secretfile "r"]
+ set secret [gets $secretfd]
+ close $secretfd
+
+ ## Compute basic key
+ set key [list $secret $build_platform $cache_tcl_version $cache_kitcreator_version $build_packages]
+
+ ## Update key with options in deterministic order
+ foreach option [lsort -dictionary [array names build_options]] {
+ lappend key [list "option:$option" $build_options($option)]
+ }
+
+ ## Convert key to a user-consumable string via hashing
+ set key [string tolower [sha1::sha1 -hex $key]]
+
+ # Determine filename
+ if {$build_options(kitdll)} {
+ set extension "so"
+ switch -- $build_platform {
+ "win32" - "win64" {
+ set extension "dll"
+ }
+ "hpux-hppa64" {
+ set extension "sl"
+ }
+ }
+
+ ## XXX: TODO: The version here needs to match what's in the SONAME
+ set filename "libtclkit[string map [list "." ""] ${cache_tcl_version}].${extension}"
+ } else {
+ set filename "tclkit"
+
+ switch -- $build_platform {
+ "win32" - "win64" {
+ append filename ".exe"
+ }
+ }
+ }
+
+ # Queue build up and wait for it to complete
+ set fd [open $queue a+]
+ puts $fd [list filename $filename key $key platform $build_platform tcl_version $build_tcl_version kitcreator_version $build_kitcreator_version packages $build_packages options [array get build_options]]
+ close $fd
+
+ set url "http://kitcreator.rkeene.org/kits/building/$key/"
+
+ headers redirect $url
+?>
+
+ KitCreator, Web Interface
+
+
+ KitCreator Web Interface
+ Build in progress, output will be: puts -nonewline $url ?>
+
+
+
+ } else {
?>
KitCreator, Web Interface
-
+
KitCreator Web Interface
-
+ } ?>
ADDED build/web/kitcreator.vfs/lib/.htaccess
Index: build/web/kitcreator.vfs/lib/.htaccess
==================================================================
--- /dev/null
+++ build/web/kitcreator.vfs/lib/.htaccess
@@ -0,0 +1,1 @@
+Deny from all
ADDED build/web/kitcreator.vfs/lib/sha1-2.0.3/pkgIndex.tcl
Index: build/web/kitcreator.vfs/lib/sha1-2.0.3/pkgIndex.tcl
==================================================================
--- /dev/null
+++ build/web/kitcreator.vfs/lib/sha1-2.0.3/pkgIndex.tcl
@@ -0,0 +1,1 @@
+package ifneeded sha1 2.0.3 [list source [file join $dir sha1.tcl]]
ADDED build/web/kitcreator.vfs/lib/sha1-2.0.3/sha1.tcl
Index: build/web/kitcreator.vfs/lib/sha1-2.0.3/sha1.tcl
==================================================================
--- /dev/null
+++ build/web/kitcreator.vfs/lib/sha1-2.0.3/sha1.tcl
@@ -0,0 +1,827 @@
+# sha1.tcl -
+
+# @@ Meta Begin
+# Package sha1 2.0.3
+# Meta platform tcl
+# Meta rsk::build::date 2011-03-30
+# Meta description Part of the Tclib sha1 module
+# Meta require {Tcl 8.2}
+# @@ Meta End
+
+#
+# Copyright (C) 2001 Don Libes
+# Copyright (C) 2003 Pat Thoyts
+#
+# SHA1 defined by FIPS 180-1, "The SHA1 Message-Digest Algorithm"
+# HMAC defined by RFC 2104, "Keyed-Hashing for Message Authentication"
+#
+# This is an implementation of SHA1 based upon the example code given in
+# FIPS 180-1 and upon the tcllib MD4 implementation and taking some ideas
+# and methods from the earlier tcllib sha1 version by Don Libes.
+#
+# This implementation permits incremental updating of the hash and
+# provides support for external compiled implementations either using
+# critcl (sha1c) or Trf.
+#
+# ref: http://www.itl.nist.gov/fipspubs/fip180-1.htm
+#
+# -------------------------------------------------------------------------
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# -------------------------------------------------------------------------
+#
+# $Id: sha1.tcl,v 1.22 2009/05/07 00:35:10 patthoyts Exp $
+
+# @mdgen EXCLUDE: sha1c.tcl
+
+package require Tcl 8.2; # tcl minimum version
+
+namespace eval ::sha1 {
+ variable version 2.0.3
+ variable rcsid {$Id: sha1.tcl,v 1.22 2009/05/07 00:35:10 patthoyts Exp $}
+
+ variable accel
+ array set accel {tcl 0 critcl 0 cryptkit 0 trf 0}
+ variable loaded {}
+ variable active
+ array set active {tcl 0 critcl 0 cryptkit 0 trf 0}
+
+ namespace export sha1 hmac SHA1Init SHA1Update SHA1Final
+
+ variable uid
+ if {![info exists uid]} {
+ set uid 0
+ }
+}
+
+# -------------------------------------------------------------------------
+# Management of sha1 implementations.
+
+# LoadAccelerator --
+#
+# This package can make use of a number of compiled extensions to
+# accelerate the digest computation. This procedure manages the
+# use of these extensions within the package. During normal usage
+# this should not be called, but the test package manipulates the
+# list of enabled accelerators.
+#
+proc ::sha1::LoadAccelerator {name} {
+ variable accel
+ set r 0
+ switch -exact -- $name {
+ tcl {
+ # Already present (this file)
+ set r 1
+ }
+ critcl {
+ if {![catch {package require tcllibc}]
+ || ![catch {package require sha1c}]} {
+ set r [expr {[info command ::sha1::sha1c] != {}}]
+ }
+ }
+ cryptkit {
+ if {![catch {package require cryptkit}]} {
+ set r [expr {![catch {cryptkit::cryptInit}]}]
+ }
+ }
+ trf {
+ if {![catch {package require Trf}]} {
+ set r [expr {![catch {::sha1 aa} msg]}]
+ }
+ }
+ default {
+ return -code error "invalid accelerator $key:\
+ must be one of [join [KnownImplementations] {, }]"
+ }
+ }
+ set accel($name) $r
+ return $r
+}
+
+# ::sha1::Implementations --
+#
+# Determines which implementations are
+# present, i.e. loaded.
+#
+# Arguments:
+# None.
+#
+# Results:
+# A list of implementation keys.
+
+proc ::sha1::Implementations {} {
+ variable accel
+ set res {}
+ foreach n [array names accel] {
+ if {!$accel($n)} continue
+ lappend res $n
+ }
+ return $res
+}
+
+# ::sha1::KnownImplementations --
+#
+# Determines which implementations are known
+# as possible implementations.
+#
+# Arguments:
+# None.
+#
+# Results:
+# A list of implementation keys. In the order
+# of preference, most prefered first.
+
+proc ::sha1::KnownImplementations {} {
+ return {critcl cryptkit trf tcl}
+}
+
+proc ::sha1::Names {} {
+ return {
+ critcl {tcllibc based}
+ cryptkit {cryptkit based}
+ trf {Trf based}
+ tcl {pure Tcl}
+ }
+}
+
+# ::sha1::SwitchTo --
+#
+# Activates a loaded named implementation.
+#
+# Arguments:
+# key Name of the implementation to activate.
+#
+# Results:
+# None.
+
+proc ::sha1::SwitchTo {key} {
+ variable accel
+ variable active
+ variable loaded
+
+ if {[string equal $key $loaded]} {
+ # No change, nothing to do.
+ return
+ } elseif {![string equal $key ""]} {
+ # Validate the target implementation of the switch.
+
+ if {![info exists accel($key)]} {
+ return -code error "Unable to activate unknown implementation \"$key\""
+ } elseif {![info exists accel($key)] || !$accel($key)} {
+ return -code error "Unable to activate missing implementation \"$key\""
+ }
+ }
+
+ if {![string equal $loaded ""]} {
+ set active($loaded) 0
+ }
+ if {![string equal $key ""]} {
+ set active($key) 1
+ }
+
+ # Remember the active implementation, for deactivation by future
+ # switches.
+
+ set loaded $key
+ return
+}
+
+# -------------------------------------------------------------------------
+
+# SHA1Init --
+#
+# Create and initialize an SHA1 state variable. This will be
+# cleaned up when we call SHA1Final
+#
+
+proc ::sha1::SHA1Init {} {
+ variable active
+ variable uid
+ set token [namespace current]::[incr uid]
+ upvar #0 $token state
+
+ # FIPS 180-1: 7 - Initialize the hash state
+ array set state \
+ [list \
+ A [expr {int(0x67452301)}] \
+ B [expr {int(0xEFCDAB89)}] \
+ C [expr {int(0x98BADCFE)}] \
+ D [expr {int(0x10325476)}] \
+ E [expr {int(0xC3D2E1F0)}] \
+ n 0 i "" ]
+ if {$active(cryptkit)} {
+ cryptkit::cryptCreateContext state(ckctx) CRYPT_UNUSED CRYPT_ALGO_SHA
+ } elseif {$active(trf)} {
+ set s {}
+ switch -exact -- $::tcl_platform(platform) {
+ windows { set s [open NUL w] }
+ unix { set s [open /dev/null w] }
+ }
+ if {$s != {}} {
+ fconfigure $s -translation binary -buffering none
+ ::sha1 -attach $s -mode write \
+ -read-type variable \
+ -read-destination [subst $token](trfread) \
+ -write-type variable \
+ -write-destination [subst $token](trfwrite)
+ array set state [list trfread 0 trfwrite 0 trf $s]
+ }
+ }
+ return $token
+}
+
+# SHA1Update --
+#
+# This is called to add more data into the hash. You may call this
+# as many times as you require. Note that passing in "ABC" is equivalent
+# to passing these letters in as separate calls -- hence this proc
+# permits hashing of chunked data
+#
+# If we have a C-based implementation available, then we will use
+# it here in preference to the pure-Tcl implementation.
+#
+proc ::sha1::SHA1Update {token data} {
+ variable active
+ upvar #0 $token state
+
+ if {$active(critcl)} {
+ if {[info exists state(sha1c)]} {
+ set state(sha1c) [sha1c $data $state(sha1c)]
+ } else {
+ set state(sha1c) [sha1c $data]
+ }
+ return
+ } elseif {[info exists state(ckctx)]} {
+ if {[string length $data] > 0} {
+ cryptkit::cryptEncrypt $state(ckctx) $data
+ }
+ return
+ } elseif {[info exists state(trf)]} {
+ puts -nonewline $state(trf) $data
+ return
+ }
+
+ # Update the state values
+ incr state(n) [string length $data]
+ append state(i) $data
+
+ # Calculate the hash for any complete blocks
+ set len [string length $state(i)]
+ for {set n 0} {($n + 64) <= $len} {} {
+ SHA1Transform $token [string range $state(i) $n [incr n 64]]
+ }
+
+ # Adjust the state for the blocks completed.
+ set state(i) [string range $state(i) $n end]
+ return
+}
+
+# SHA1Final --
+#
+# This procedure is used to close the current hash and returns the
+# hash data. Once this procedure has been called the hash context
+# is freed and cannot be used again.
+#
+# Note that the output is 160 bits represented as binary data.
+#
+proc ::sha1::SHA1Final {token} {
+ upvar #0 $token state
+
+ # Check for either of the C-compiled versions.
+ if {[info exists state(sha1c)]} {
+ set r $state(sha1c)
+ unset state
+ return $r
+ } elseif {[info exists state(ckctx)]} {
+ cryptkit::cryptEncrypt $state(ckctx) ""
+ cryptkit::cryptGetAttributeString $state(ckctx) \
+ CRYPT_CTXINFO_HASHVALUE r 20
+ cryptkit::cryptDestroyContext $state(ckctx)
+ # If nothing was hashed, we get no r variable set!
+ if {[info exists r]} {
+ unset state
+ return $r
+ }
+ } elseif {[info exists state(trf)]} {
+ close $state(trf)
+ set r $state(trfwrite)
+ unset state
+ return $r
+ }
+
+ # Padding
+ #
+ set len [string length $state(i)]
+ set pad [expr {56 - ($len % 64)}]
+ if {$len % 64 > 56} {
+ incr pad 64
+ }
+ if {$pad == 0} {
+ incr pad 64
+ }
+ append state(i) [binary format a$pad \x80]
+
+ # Append length in bits as big-endian wide int.
+ set dlen [expr {8 * $state(n)}]
+ append state(i) [binary format II 0 $dlen]
+
+ # Calculate the hash for the remaining block.
+ set len [string length $state(i)]
+ for {set n 0} {($n + 64) <= $len} {} {
+ SHA1Transform $token [string range $state(i) $n [incr n 64]]
+ }
+
+ # Output
+ set r [bytes $state(A)][bytes $state(B)][bytes $state(C)][bytes $state(D)][bytes $state(E)]
+ unset state
+ return $r
+}
+
+# -------------------------------------------------------------------------
+# HMAC Hashed Message Authentication (RFC 2104)
+#
+# hmac = H(K xor opad, H(K xor ipad, text))
+#
+
+# HMACInit --
+#
+# This is equivalent to the SHA1Init procedure except that a key is
+# added into the algorithm
+#
+proc ::sha1::HMACInit {K} {
+
+ # Key K is adjusted to be 64 bytes long. If K is larger, then use
+ # the SHA1 digest of K and pad this instead.
+ set len [string length $K]
+ if {$len > 64} {
+ set tok [SHA1Init]
+ SHA1Update $tok $K
+ set K [SHA1Final $tok]
+ set len [string length $K]
+ }
+ set pad [expr {64 - $len}]
+ append K [string repeat \0 $pad]
+
+ # Cacluate the padding buffers.
+ set Ki {}
+ set Ko {}
+ binary scan $K i16 Ks
+ foreach k $Ks {
+ append Ki [binary format i [expr {$k ^ 0x36363636}]]
+ append Ko [binary format i [expr {$k ^ 0x5c5c5c5c}]]
+ }
+
+ set tok [SHA1Init]
+ SHA1Update $tok $Ki; # initialize with the inner pad
+
+ # preserve the Ko value for the final stage.
+ # FRINK: nocheck
+ set [subst $tok](Ko) $Ko
+
+ return $tok
+}
+
+# HMACUpdate --
+#
+# Identical to calling SHA1Update
+#
+proc ::sha1::HMACUpdate {token data} {
+ SHA1Update $token $data
+ return
+}
+
+# HMACFinal --
+#
+# This is equivalent to the SHA1Final procedure. The hash context is
+# closed and the binary representation of the hash result is returned.
+#
+proc ::sha1::HMACFinal {token} {
+ upvar #0 $token state
+
+ set tok [SHA1Init]; # init the outer hashing function
+ SHA1Update $tok $state(Ko); # prepare with the outer pad.
+ SHA1Update $tok [SHA1Final $token]; # hash the inner result
+ return [SHA1Final $tok]
+}
+
+# -------------------------------------------------------------------------
+# Description:
+# This is the core SHA1 algorithm. It is a lot like the MD4 algorithm but
+# includes an extra round and a set of constant modifiers throughout.
+#
+set ::sha1::SHA1Transform_body {
+ upvar #0 $token state
+
+ # FIPS 180-1: 7a: Process Message in 16-Word Blocks
+ binary scan $msg I* blocks
+ set blockLen [llength $blocks]
+ for {set i 0} {$i < $blockLen} {incr i 16} {
+ set W [lrange $blocks $i [expr {$i+15}]]
+
+ # FIPS 180-1: 7b: Expand the input into 80 words
+ # For t = 16 to 79
+ # let Wt = (Wt-3 ^ Wt-8 ^ Wt-14 ^ Wt-16) <<< 1
+ set t3 12
+ set t8 7
+ set t14 1
+ set t16 -1
+ for {set t 16} {$t < 80} {incr t} {
+ set x [expr {[lindex $W [incr t3]] ^ [lindex $W [incr t8]] ^ \
+ [lindex $W [incr t14]] ^ [lindex $W [incr t16]]}]
+ lappend W [expr {int(($x << 1) | (($x >> 31) & 1))}]
+ }
+
+ # FIPS 180-1: 7c: Copy hash state.
+ set A $state(A)
+ set B $state(B)
+ set C $state(C)
+ set D $state(D)
+ set E $state(E)
+
+ # FIPS 180-1: 7d: Do permutation rounds
+ # For t = 0 to 79 do
+ # TEMP = (A<<<5) + ft(B,C,D) + E + Wt + Kt;
+ # E = D; D = C; C = S30(B); B = A; A = TEMP;
+
+ # Round 1: ft(B,C,D) = (B & C) | (~B & D) ( 0 <= t <= 19)
+ for {set t 0} {$t < 20} {incr t} {
+ set TEMP [F1 $A $B $C $D $E [lindex $W $t]]
+ set E $D
+ set D $C
+ set C [rotl32 $B 30]
+ set B $A
+ set A $TEMP
+ }
+
+ # Round 2: ft(B,C,D) = (B ^ C ^ D) ( 20 <= t <= 39)
+ for {} {$t < 40} {incr t} {
+ set TEMP [F2 $A $B $C $D $E [lindex $W $t]]
+ set E $D
+ set D $C
+ set C [rotl32 $B 30]
+ set B $A
+ set A $TEMP
+ }
+
+ # Round 3: ft(B,C,D) = ((B & C) | (B & D) | (C & D)) ( 40 <= t <= 59)
+ for {} {$t < 60} {incr t} {
+ set TEMP [F3 $A $B $C $D $E [lindex $W $t]]
+ set E $D
+ set D $C
+ set C [rotl32 $B 30]
+ set B $A
+ set A $TEMP
+ }
+
+ # Round 4: ft(B,C,D) = (B ^ C ^ D) ( 60 <= t <= 79)
+ for {} {$t < 80} {incr t} {
+ set TEMP [F4 $A $B $C $D $E [lindex $W $t]]
+ set E $D
+ set D $C
+ set C [rotl32 $B 30]
+ set B $A
+ set A $TEMP
+ }
+
+ # Then perform the following additions. (That is, increment each
+ # of the four registers by the value it had before this block
+ # was started.)
+ incr state(A) $A
+ incr state(B) $B
+ incr state(C) $C
+ incr state(D) $D
+ incr state(E) $E
+ }
+
+ return
+}
+
+proc ::sha1::F1 {A B C D E W} {
+ expr {(((($A << 5) & 0xffffffff) | (($A >> 27) & 0x1f)) \
+ + ($D ^ ($B & ($C ^ $D))) + $E + $W + 0x5a827999) & 0xffffffff}
+}
+
+proc ::sha1::F2 {A B C D E W} {
+ expr {(((($A << 5) & 0xffffffff) | (($A >> 27) & 0x1f)) \
+ + ($B ^ $C ^ $D) + $E + $W + 0x6ed9eba1) & 0xffffffff}
+}
+
+proc ::sha1::F3 {A B C D E W} {
+ expr {(((($A << 5) & 0xffffffff)| (($A >> 27) & 0x1f)) \
+ + (($B & $C) | ($D & ($B | $C))) + $E + $W + 0x8f1bbcdc) & 0xffffffff}
+}
+
+proc ::sha1::F4 {A B C D E W} {
+ expr {(((($A << 5) & 0xffffffff)| (($A >> 27) & 0x1f)) \
+ + ($B ^ $C ^ $D) + $E + $W + 0xca62c1d6) & 0xffffffff}
+}
+
+proc ::sha1::rotl32 {v n} {
+ return [expr {((($v << $n) \
+ | (($v >> (32 - $n)) \
+ & (0x7FFFFFFF >> (31 - $n))))) \
+ & 0xFFFFFFFF}]
+}
+
+
+# -------------------------------------------------------------------------
+#
+# In order to get this code to go as fast as possible while leaving
+# the main code readable we can substitute the above function bodies
+# into the transform procedure. This inlines the code for us an avoids
+# a procedure call overhead within the loops.
+#
+# We can do some minor tweaking to improve speed on Tcl < 8.5 where we
+# know our arithmetic is limited to 64 bits. On > 8.5 we may have
+# unconstrained integer arithmetic and must avoid letting it run away.
+#
+
+regsub -all -line \
+ {\[F1 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body \
+ {[expr {(rotl32($A,5) + ($D ^ ($B \& ($C ^ $D))) + $E + \1 + 0x5a827999) \& 0xffffffff}]} \
+ ::sha1::SHA1Transform_body_tmp
+
+regsub -all -line \
+ {\[F2 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp \
+ {[expr {(rotl32($A,5) + ($B ^ $C ^ $D) + $E + \1 + 0x6ed9eba1) \& 0xffffffff}]} \
+ ::sha1::SHA1Transform_body_tmp
+
+regsub -all -line \
+ {\[F3 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp \
+ {[expr {(rotl32($A,5) + (($B \& $C) | ($D \& ($B | $C))) + $E + \1 + 0x8f1bbcdc) \& 0xffffffff}]} \
+ ::sha1::SHA1Transform_body_tmp
+
+regsub -all -line \
+ {\[F4 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp \
+ {[expr {(rotl32($A,5) + ($B ^ $C ^ $D) + $E + \1 + 0xca62c1d6) \& 0xffffffff}]} \
+ ::sha1::SHA1Transform_body_tmp
+
+regsub -all -line \
+ {rotl32\(\$A,5\)} \
+ $::sha1::SHA1Transform_body_tmp \
+ {((($A << 5) \& 0xffffffff) | (($A >> 27) \& 0x1f))} \
+ ::sha1::SHA1Transform_body_tmp
+
+regsub -all -line \
+ {\[rotl32 \$B 30\]} \
+ $::sha1::SHA1Transform_body_tmp \
+ {[expr {int(($B << 30) | (($B >> 2) \& 0x3fffffff))}]} \
+ ::sha1::SHA1Transform_body_tmp
+#
+# Version 2 avoids a few truncations to 32 bits in non-essential places.
+#
+regsub -all -line \
+ {\[F1 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body \
+ {[expr {rotl32($A,5) + ($D ^ ($B \& ($C ^ $D))) + $E + \1 + 0x5a827999}]} \
+ ::sha1::SHA1Transform_body_tmp2
+
+regsub -all -line \
+ {\[F2 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp2 \
+ {[expr {rotl32($A,5) + ($B ^ $C ^ $D) + $E + \1 + 0x6ed9eba1}]} \
+ ::sha1::SHA1Transform_body_tmp2
+
+regsub -all -line \
+ {\[F3 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp2 \
+ {[expr {rotl32($A,5) + (($B \& $C) | ($D \& ($B | $C))) + $E + \1 + 0x8f1bbcdc}]} \
+ ::sha1::SHA1Transform_body_tmp2
+
+regsub -all -line \
+ {\[F4 \$A \$B \$C \$D \$E (\[.*?\])\]} \
+ $::sha1::SHA1Transform_body_tmp2 \
+ {[expr {rotl32($A,5) + ($B ^ $C ^ $D) + $E + \1 + 0xca62c1d6}]} \
+ ::sha1::SHA1Transform_body_tmp2
+
+regsub -all -line \
+ {rotl32\(\$A,5\)} \
+ $::sha1::SHA1Transform_body_tmp2 \
+ {(($A << 5) | (($A >> 27) \& 0x1f))} \
+ ::sha1::SHA1Transform_body_tmp2
+
+regsub -all -line \
+ {\[rotl32 \$B 30\]} \
+ $::sha1::SHA1Transform_body_tmp2 \
+ {[expr {($B << 30) | (($B >> 2) \& 0x3fffffff)}]} \
+ ::sha1::SHA1Transform_body_tmp2
+
+if {[package vsatisfies [package provide Tcl] 8.5]} {
+ proc ::sha1::SHA1Transform {token msg} $::sha1::SHA1Transform_body_tmp
+} else {
+ proc ::sha1::SHA1Transform {token msg} $::sha1::SHA1Transform_body_tmp2
+}
+
+unset ::sha1::SHA1Transform_body
+unset ::sha1::SHA1Transform_body_tmp
+unset ::sha1::SHA1Transform_body_tmp2
+
+# -------------------------------------------------------------------------
+
+proc ::sha1::byte {n v} {expr {((0xFF << (8 * $n)) & $v) >> (8 * $n)}}
+proc ::sha1::bytes {v} {
+ #format %c%c%c%c [byte 0 $v] [byte 1 $v] [byte 2 $v] [byte 3 $v]
+ format %c%c%c%c \
+ [expr {((0xFF000000 & $v) >> 24) & 0xFF}] \
+ [expr {(0xFF0000 & $v) >> 16}] \
+ [expr {(0xFF00 & $v) >> 8}] \
+ [expr {0xFF & $v}]
+}
+
+# -------------------------------------------------------------------------
+
+proc ::sha1::Hex {data} {
+ binary scan $data H* result
+ return $result
+}
+
+# -------------------------------------------------------------------------
+
+# Description:
+# Pop the nth element off a list. Used in options processing.
+#
+proc ::sha1::Pop {varname {nth 0}} {
+ upvar $varname args
+ set r [lindex $args $nth]
+ set args [lreplace $args $nth $nth]
+ return $r
+}
+
+# -------------------------------------------------------------------------
+
+# fileevent handler for chunked file hashing.
+#
+proc ::sha1::Chunk {token channel {chunksize 4096}} {
+ upvar #0 $token state
+
+ if {[eof $channel]} {
+ fileevent $channel readable {}
+ set state(reading) 0
+ }
+
+ SHA1Update $token [read $channel $chunksize]
+}
+
+# -------------------------------------------------------------------------
+
+proc ::sha1::sha1 {args} {
+ array set opts {-hex 0 -filename {} -channel {} -chunksize 4096}
+ if {[llength $args] == 1} {
+ set opts(-hex) 1
+ } else {
+ while {[string match -* [set option [lindex $args 0]]]} {
+ switch -glob -- $option {
+ -hex { set opts(-hex) 1 }
+ -bin { set opts(-hex) 0 }
+ -file* { set opts(-filename) [Pop args 1] }
+ -channel { set opts(-channel) [Pop args 1] }
+ -chunksize { set opts(-chunksize) [Pop args 1] }
+ default {
+ if {[llength $args] == 1} { break }
+ if {[string compare $option "--"] == 0} { Pop args; break }
+ set err [join [lsort [concat -bin [array names opts]]] ", "]
+ return -code error "bad option $option:\
+ must be one of $err"
+ }
+ }
+ Pop args
+ }
+ }
+
+ if {$opts(-filename) != {}} {
+ set opts(-channel) [open $opts(-filename) r]
+ fconfigure $opts(-channel) -translation binary
+ }
+
+ if {$opts(-channel) == {}} {
+
+ if {[llength $args] != 1} {
+ return -code error "wrong # args:\
+ should be \"sha1 ?-hex? -filename file | string\""
+ }
+ set tok [SHA1Init]
+ SHA1Update $tok [lindex $args 0]
+ set r [SHA1Final $tok]
+
+ } else {
+
+ set tok [SHA1Init]
+ # FRINK: nocheck
+ set [subst $tok](reading) 1
+ fileevent $opts(-channel) readable \
+ [list [namespace origin Chunk] \
+ $tok $opts(-channel) $opts(-chunksize)]
+ # FRINK: nocheck
+ vwait [subst $tok](reading)
+ set r [SHA1Final $tok]
+
+ # If we opened the channel - we should close it too.
+ if {$opts(-filename) != {}} {
+ close $opts(-channel)
+ }
+ }
+
+ if {$opts(-hex)} {
+ set r [Hex $r]
+ }
+ return $r
+}
+
+# -------------------------------------------------------------------------
+
+proc ::sha1::hmac {args} {
+ array set opts {-hex 1 -filename {} -channel {} -chunksize 4096}
+ if {[llength $args] != 2} {
+ while {[string match -* [set option [lindex $args 0]]]} {
+ switch -glob -- $option {
+ -key { set opts(-key) [Pop args 1] }
+ -hex { set opts(-hex) 1 }
+ -bin { set opts(-hex) 0 }
+ -file* { set opts(-filename) [Pop args 1] }
+ -channel { set opts(-channel) [Pop args 1] }
+ -chunksize { set opts(-chunksize) [Pop args 1] }
+ default {
+ if {[llength $args] == 1} { break }
+ if {[string compare $option "--"] == 0} { Pop args; break }
+ set err [join [lsort [array names opts]] ", "]
+ return -code error "bad option $option:\
+ must be one of $err"
+ }
+ }
+ Pop args
+ }
+ }
+
+ if {[llength $args] == 2} {
+ set opts(-key) [Pop args]
+ }
+
+ if {![info exists opts(-key)]} {
+ return -code error "wrong # args:\
+ should be \"hmac ?-hex? -key key -filename file | string\""
+ }
+
+ if {$opts(-filename) != {}} {
+ set opts(-channel) [open $opts(-filename) r]
+ fconfigure $opts(-channel) -translation binary
+ }
+
+ if {$opts(-channel) == {}} {
+
+ if {[llength $args] != 1} {
+ return -code error "wrong # args:\
+ should be \"hmac ?-hex? -key key -filename file | string\""
+ }
+ set tok [HMACInit $opts(-key)]
+ HMACUpdate $tok [lindex $args 0]
+ set r [HMACFinal $tok]
+
+ } else {
+
+ set tok [HMACInit $opts(-key)]
+ # FRINK: nocheck
+ set [subst $tok](reading) 1
+ fileevent $opts(-channel) readable \
+ [list [namespace origin Chunk] \
+ $tok $opts(-channel) $opts(-chunksize)]
+ # FRINK: nocheck
+ vwait [subst $tok](reading)
+ set r [HMACFinal $tok]
+
+ # If we opened the channel - we should close it too.
+ if {$opts(-filename) != {}} {
+ close $opts(-channel)
+ }
+ }
+
+ if {$opts(-hex)} {
+ set r [Hex $r]
+ }
+ return $r
+}
+
+# -------------------------------------------------------------------------
+
+# Try and load a compiled extension to help.
+namespace eval ::sha1 {
+ variable e {}
+ foreach e [KnownImplementations] {
+ if {[LoadAccelerator $e]} {
+ SwitchTo $e
+ break
+ }
+ }
+ unset e
+}
+
+package provide sha1 $::sha1::version
+
+# -------------------------------------------------------------------------
+# Local Variables:
+# mode: tcl
+# indent-tabs-mode: nil
+# End:
ADDED build/web/process_queue
Index: build/web/process_queue
==================================================================
--- /dev/null
+++ build/web/process_queue
@@ -0,0 +1,115 @@
+#! /usr/bin/env tclsh
+
+set queue "/home/rkeene/devel/kitcreator/build/web/queue"
+set outdir "/web/customers/kitcreator.rkeene.org/kits"
+
+if {![file exists "${queue}.old"]} {
+ if {![file exists $queue]} {
+ exit 0
+ }
+
+ file rename "$queue" "${queue}.old"
+}
+set queue "${queue}.old"
+
+set fd [open $queue r]
+set data [read $fd]
+close $fd
+
+foreach line [split $data "\n"] {
+ if {$line == ""} {
+ continue
+ }
+
+ unset -nocomplain buildinfo
+
+ array set buildinfo $line
+
+ set outfile [file join $outdir $buildinfo(key) $buildinfo(filename)]
+
+ # Skip if build completed
+ if {[file exists $outfile]} {
+ continue
+ }
+
+ # Skip if build failed
+ if {[file exists $outfile.buildfail]} {
+ continue
+ }
+
+ set workdir [file join $outdir $buildinfo(key) build]
+ file delete -force $workdir
+ file mkdir $workdir
+ cd $workdir
+
+ set fd [open ../filename w]
+ puts $fd $buildinfo(filename)
+ close $fd
+
+ set tarball kitcreator-${buildinfo(kitcreator_version)}.tar.gz
+ exec wget -q -O $tarball http://kitcreator.rkeene.org/fossil/tarball/${tarball}?uuid=${buildinfo(kitcreator_version)}
+ exec gzip -dc $tarball | tar -xf -
+ cd kitcreator-${buildinfo(kitcreator_version)}
+
+ set script "./build/make-kit-${buildinfo(platform)}"
+ set args [list]
+
+ set ::env(KITCREATOR_PKGS) " [join $buildinfo(packages) " "] "
+
+ foreach {option value} $buildinfo(options) {
+ switch -- $option {
+ "kitdll" {
+ if {$value} {
+ set ::env(KITCREATOR_PKGS) "$::env(KITCREATOR_PKGS) kitdll"
+ }
+ }
+ "threaded" {
+ if {$value} {
+ lappend args "--enable-threads"
+ }
+ }
+ }
+ }
+
+ catch {
+ exec ./build/pre.sh
+ }
+
+ catch {
+ exec $script $buildinfo(tcl_version) {*}$args > "${outfile}.log" 2>@1
+ }
+
+ catch {
+ exec grep ^ {*}[glob */build.log] >> "${outfile}.log"
+ }
+
+ foreach file [list tclkit-$buildinfo(tcl_version) {*}[glob -nocomplain libtclkit*]] {
+ switch -glob -- $file {
+ "*.dylib" - "*.so" - "*.sl" - "*.dll" { }
+ "tclkit-*" {}
+ default {
+ continue
+ }
+ }
+
+ if {[file exists $file]} {
+ file rename $file $outfile
+
+ break
+ }
+ }
+
+ if {![file exists $outfile]} {
+ set fd [open $outfile.buildfail "w+"]
+ puts $fd "$line"
+ close $fd
+ }
+
+ cd $outdir
+
+ file delete -force $workdir
+}
+
+file delete $queue
+
+exit 0