--- src/port1.0/portchecksum.tcl.b	Tue Sep  7 23:34:59 2004
+++ src/port1.0/portchecksum.tcl	Wed Sep 15 13:08:06 2004
@@ -45,15 +45,17 @@
 
 set_ui_prefix
 
-# dmd5
+# get_checksum
 #
-# Returns the expected checksum for the given file.
-# If no checksum is found, returns -1.
+# Returns the expected md5/sha1/etc. checksum for the given file.
+# If no md5/sha1/etc. checksum is found, returns -1.
 #
-proc dmd5 {file} {
-	foreach {name type sum} [option checksums] {
+proc get_checksum {file want_sum port_checksums} {
+	foreach {name type sum} $port_checksums {
 		if {[string equal $name $file]} {
-			return $sum
+			if {[string equal $type $want_sum]} {
+				return $sum
+			}
 		}
 	}
 
@@ -77,45 +79,120 @@
 proc checksum_main {args} {
 	global UI_PREFIX all_dist_files
 
+	# list of known checksum types as an
+	# array of string in portfile and function we'll call.
+	# The string and the function are currently the same, but no
+	# guarantees that it will remain so.
+	array set checksum_types { \
+		"md5"	md5 \
+		"sha1"	sha1 \
+	}
+
 	# If no files have been downloaded, there is nothing to checksum.
 	if {![info exists all_dist_files]} {
 		return 0
 	}
 
 	# Optimization for the two-argument case for checksums.
-	if {[llength [option checksums]] == 2 && [llength $all_dist_files] == 1} {
-		option checksums [linsert [option checksums] 0 $all_dist_files]
+	## See if the checksum type from the Portfile matches a known
+	## checksum type.  If it does and we only have 1 distfile,
+	## insert the distfilename ahead of the checksum type and result
+	## from the Portfile. 
+	## If the type doesn't match a known type and we only have 1 distfile,
+	## then its an unknown checksum type, so we barf on it.
+	## ELACKSGRACE:  if a Portfile only has 1 distfile *and* the two-arg
+	## optimization is not used (i.e. checksum line is <distfile> <type> <sum>)
+	## this code thinks that <distfile> is the <type> and barfs on it.
+	## I'm not seeing a way around that right now, as the Portfile checksum
+	## info comes to us as a list of items.
+	## AND THERE WE GO: graphics/aalib has 1 distfile and doesn't use the
+	## two-arg optimization, so it barfs.  futzor.
+	## okay, so now what we'll do is just ignore bogus checksum types.
+	## We *should* detect bogus checksum types, I'm thinking that changes
+	## need to happen in reading the Portfile and perform the substitution
+	## for the two-arg optimization during the building of the checksums option.
+	##
+	set port_checksums ""
+	foreach {type sum} [option checksums] {
+		## see if $type is one of our known checksum types.  If it is, 
+		## we assume we don't have our dist file name.  Check that
+		## we only expect 1 dist file as well...  If we have only
+		## one dist file and $type is a checksum_type, the add the
+		## $all_dist_files to the start of the checksum list.
+
+		if {[lsearch -exact [array names checksum_types] $type] != -1 && \
+			[llength $all_dist_files] == 1} {
+			set port_checksums [linsert $port_checksums 0 $all_dist_files $type $sum]
+##		} else {
+##			if {[llength $all_dist_files] == 1} {
+##				return -code error "[format [msgcat::mc "Unknown checksum type '%s'"] $type]"
+##			}
+		}
+	}
+	## if we didn't do the above filename insertions, we have an empty $port_checksums,
+	## so copy over the [option checksums] and use $port_checksums from here out
+	if {[llength $port_checksums] == 0} {
+		set port_checksums [option checksums]
 	}
 
 	set fail no
 
 	foreach distfile $all_dist_files {
 		ui_info "$UI_PREFIX [format [msgcat::mc "Checksumming %s"] $distfile]"
+		set distfile_chksum_success 0
 
-		# Calculate the distfile's checksum.
-		set checksum [md5 file [file join [option distpath] $distfile]]
-
-		# Find the expected checksum.
-		set dchecksum [dmd5 $distfile]
-
-		# Check for missing checksum or a mismatch.
-		if {$dchecksum == -1} {
-			ui_error "[format [msgcat::mc "No checksum set for %s"] $distfile]"
-		} elseif {![string equal $checksum $dchecksum]} {
-			ui_error "[format [msgcat::mc "Checksum mismatch for %s"] $distfile]"
-		} else {
-			continue
+		## XYZZY: as I look at this again, I'm thinking maybe we're doing
+		## it backwards - rather than calculate the checksum then go look for
+		## it, we should find the checksums we do have, then calculate those
+		## and compare, and note our successes.  We can then show those
+		## checksum types we know about that were not in the Portfile, and
+		## make mention of it.
+		foreach chksum_type [array names checksum_types] {
+			# Find the expected checksum.
+			set dchecksum [get_checksum $distfile $chksum_type $port_checksums]
+
+			# Check for missing checksum
+			if {$dchecksum == -1} {
+				ui_info "$UI_PREFIX [format [msgcat::mc "No %s checksum set for %s"] $chksum_type $distfile]"
+				## and lets try the next one...
+				continue
+			}
+			## sanity check - Do we actually have checksum routine?
+			if {[string length [info commands $checksum_types($chksum_type)]]} {
+				# Calculate the distfile's checksum.
+				set checksum [$checksum_types($chksum_type) file [file join [option distpath] $distfile]]
+			} else {
+				## explode catch fire?  Just throw a warning and continue? Hmmm.
+				ui_error "$UI_PREFIX [format [msgcat::mc "Can't find checksum routine '%s' for checksum type '%s'"] $checksum_types($chksum_type) $chksum_type]"
+				continue
+			}
+
+			# Check for checksum mismatch.
+			if {![string equal $checksum $dchecksum]} {
+				ui_error "$UI_PREFIX [format [msgcat::mc "%s checksum mismatch for '%s':"] $chksum_type $distfile]"
+				ui_error "$UI_PREFIX [format [msgcat::mc "wanted '%s',"] $dchecksum]"
+				ui_error "$UI_PREFIX [format [msgcat::mc "   got '%s'"] $checksum]"
+				# Raise the failure flag
+				set fail yes
+			} else {
+				set distfile_chksum_success [expr $distfile_chksum_success + 1]
+			}
+	
+			if {[tbool fail]} {
+				return -code error "[format [msgcat::mc "Unable to verify %s checksum"] $chksum_type]"
+			}
+			## else just fall to the next checksum...
+	
+			if {$dchecksum != -1} {
+				# Post file checksum
+				ui_info "$UI_PREFIX [format [msgcat::mc "Correct %s checksum: %s %s %s"] $chksum_type ${distfile} $chksum_type ${checksum}]"
+			}
 		}
 
-		# Post file checksum
-		ui_info "[format [msgcat::mc "Correct checksum: %s %s %s"] ${distfile} md5 ${checksum}]"
-
-		# Raise the failure flag
-		set fail yes
-	}
-
-	if {[tbool fail]} {
-		return -code error "[msgcat::mc "Unable to verify file checksums"]"
+		if {$distfile_chksum_success == 0} {
+			## oh bother, no successful checksum for this dist file, bailage
+			return -code error "[format [msgcat::mc "No checksums set for %s"] $distfile]"
+		}
 	}
 
 	return 0
