@@ -1,10 +1,16 @@ #! /usr/bin/env tclsh package require http 2.7 package require sqlite3 -package require sha1 + +if {[catch { + package require sha1 +}]} { + @@SHA1.TCL@@ + package require sha1 +} namespace eval ::appfs { variable cachedir "/tmp/appfs-cache" variable ttl 3600 variable nttl 60 @@ -26,40 +32,42 @@ set file [file join $::appfs::cachedir $filekey] file mkdir [file dirname $file] - if {![file exists $file]} { - set tmpfile "${file}.new" - - set fd [open $tmpfile "w"] - fconfigure $fd -translation binary - - catch { - set token [::http::geturl $url -channel $fd -binary true] - } - - if {[info exists token]} { - set ncode [::http::ncode $token] - ::http::reset $token - } else { - set ncode "900" - } - - close $fd - - if {$keyIsHash} { - set hash [string tolower [sha1::sha1 -hex -file $tmpfile]] - } else { - set hash $key - } - - if {$ncode == "200" && $hash == $key} { - file rename -force -- $tmpfile $file - } else { - file delete -force -- $tmpfile - } + if {[file exists $file]} { + return $file + } + + set tmpfile "${file}.[expr {rand()}]" + + set fd [open $tmpfile "w"] + fconfigure $fd -translation binary + + catch { + set token [::http::geturl $url -channel $fd -binary true] + } + + if {[info exists token]} { + set ncode [::http::ncode $token] + ::http::reset $token + } else { + set ncode "900" + } + + close $fd + + if {$keyIsHash} { + set hash [string tolower [sha1::sha1 -hex -file $tmpfile]] + } else { + set hash $key + } + + if {$ncode == "200" && $hash == $key} { + file rename -force -- $tmpfile $file + } else { + file delete -force -- $tmpfile } return $file } @@ -90,10 +98,13 @@ return $os } "sunos" { return "solaris" } + "noarch" - "none" - "any" - "all" { + return "noarch" + } } return -code error "Unable to normalize OS: $os" } @@ -104,10 +115,13 @@ "i?86" { return "ix86" } "x86_64" { return $cpu + } + "noarch" - "none" - "any" - "all" { + return "noarch" } } return -code error "Unable to normalize CPU: $cpu" } @@ -139,11 +153,11 @@ proc download {hostname hash {method sha1}} { set url "http://$hostname/appfs/$method/$hash" set file [_cachefile $url $hash] if {![file exists $file]} { - return -code error "Unable to fetch" + return -code error "Unable to fetch (file does not exist: $file)" } return $file } @@ -173,11 +187,11 @@ set token [::http::geturl $url] if {[::http::ncode $token] == "200"} { set indexhash_data [::http::data $token] } ::http::reset $token - $token cleanup + ::http::cleanup $token } if {![info exists indexhash_data]} { # Cache this result for 60 seconds _db eval {INSERT OR REPLACE INTO sites (hostname, lastUpdate, ttl) VALUES ($hostname, $now, $::appfs::nttl);} @@ -209,17 +223,21 @@ } set work [split $line ","] unset -nocomplain pkgInfo - set pkgInfo(package) [lindex $work 0] - set pkgInfo(version) [lindex $work 1] - set pkgInfo(os) [_normalizeOS [lindex $work 2]] - set pkgInfo(cpuArch) [_normalizeCPU [lindex $work 3]] - set pkgInfo(hash) [string tolower [lindex $work 4]] - set pkgInfo(hash_type) "sha1" - set pkgInfo(isLatest) [expr {!![lindex $work 5]}] + if {[catch { + set pkgInfo(package) [lindex $work 0] + set pkgInfo(version) [lindex $work 1] + set pkgInfo(os) [_normalizeOS [lindex $work 2]] + set pkgInfo(cpuArch) [_normalizeCPU [lindex $work 3]] + set pkgInfo(hash) [string tolower [lindex $work 4]] + set pkgInfo(hash_type) "sha1" + set pkgInfo(isLatest) [expr {!![lindex $work 5]}] + }]} { + continue + } if {![_isHash $pkgInfo(hash)]} { continue }