Ticket #2198: base-src-port1.0-portchecksum.tcl.2.diff

File base-src-port1.0-portchecksum.tcl.2.diff, 6.5 KB (added by opendarwin.org@…, 20 years ago)

better patch for portchecksum.tcl

  • src/port1.0/portchecksum.tcl

    old new  
    4545
    4646set_ui_prefix
    4747
    48 # dmd5
     48# get_checksum
    4949#
    50 # Returns the expected checksum for the given file.
    51 # If no checksum is found, returns -1.
     50# Returns the expected md5/sha1/etc. checksum for the given file.
     51# If no md5/sha1/etc. checksum is found, returns -1.
    5252#
    53 proc dmd5 {file} {
    54         foreach {name type sum} [option checksums] {
     53proc get_checksum {file want_sum port_checksums} {
     54        foreach {name type sum} $port_checksums {
    5555                if {[string equal $name $file]} {
    56                         return $sum
     56                        if {[string equal $type $want_sum]} {
     57                                return $sum
     58                        }
    5759                }
    5860        }
    5961
     
    7779proc checksum_main {args} {
    7880        global UI_PREFIX all_dist_files
    7981
     82        # list of known checksum types as an
     83        # array of string in portfile and function we'll call.
     84        # The string and the function are currently the same, but no
     85        # guarantees that it will remain so.
     86        array set checksum_types { \
     87                "md5"   md5 \
     88                "sha1"  sha1 \
     89        }
     90
    8091        # If no files have been downloaded, there is nothing to checksum.
    8192        if {![info exists all_dist_files]} {
    8293                return 0
    8394        }
    8495
    8596        # Optimization for the two-argument case for checksums.
    86         if {[llength [option checksums]] == 2 && [llength $all_dist_files] == 1} {
    87                 option checksums [linsert [option checksums] 0 $all_dist_files]
     97        ## See if the checksum type from the Portfile matches a known
     98        ## checksum type.  If it does and we only have 1 distfile,
     99        ## insert the distfilename ahead of the checksum type and result
     100        ## from the Portfile.
     101        ## If the type doesn't match a known type and we only have 1 distfile,
     102        ## then its an unknown checksum type, so we barf on it.
     103        ## ELACKSGRACE:  if a Portfile only has 1 distfile *and* the two-arg
     104        ## optimization is not used (i.e. checksum line is <distfile> <type> <sum>)
     105        ## this code thinks that <distfile> is the <type> and barfs on it.
     106        ## I'm not seeing a way around that right now, as the Portfile checksum
     107        ## info comes to us as a list of items.
     108        ## AND THERE WE GO: graphics/aalib has 1 distfile and doesn't use the
     109        ## two-arg optimization, so it barfs.  futzor.
     110        ## okay, so now what we'll do is just ignore bogus checksum types.
     111        ## We *should* detect bogus checksum types, I'm thinking that changes
     112        ## need to happen in reading the Portfile and perform the substitution
     113        ## for the two-arg optimization during the building of the checksums option.
     114        ##
     115        set port_checksums ""
     116        foreach {type sum} [option checksums] {
     117                ## see if $type is one of our known checksum types.  If it is,
     118                ## we assume we don't have our dist file name.  Check that
     119                ## we only expect 1 dist file as well...  If we have only
     120                ## one dist file and $type is a checksum_type, the add the
     121                ## $all_dist_files to the start of the checksum list.
     122
     123                if {[lsearch -exact [array names checksum_types] $type] != -1 && \
     124                        [llength $all_dist_files] == 1} {
     125                        set port_checksums [linsert $port_checksums 0 $all_dist_files $type $sum]
     126##              } else {
     127##                      if {[llength $all_dist_files] == 1} {
     128##                              return -code error "[format [msgcat::mc "Unknown checksum type '%s'"] $type]"
     129##                      }
     130                }
     131        }
     132        ## if we didn't do the above filename insertions, we have an empty $port_checksums,
     133        ## so copy over the [option checksums] and use $port_checksums from here out
     134        if {[llength $port_checksums] == 0} {
     135                set port_checksums [option checksums]
    88136        }
    89137
    90138        set fail no
    91139
    92140        foreach distfile $all_dist_files {
    93141                ui_info "$UI_PREFIX [format [msgcat::mc "Checksumming %s"] $distfile]"
     142                set distfile_chksum_success 0
    94143
    95                 # Calculate the distfile's checksum.
    96                 set checksum [md5 file [file join [option distpath] $distfile]]
    97 
    98                 # Find the expected checksum.
    99                 set dchecksum [dmd5 $distfile]
    100 
    101                 # Check for missing checksum or a mismatch.
    102                 if {$dchecksum == -1} {
    103                         ui_error "[format [msgcat::mc "No checksum set for %s"] $distfile]"
    104                 } elseif {![string equal $checksum $dchecksum]} {
    105                         ui_error "[format [msgcat::mc "Checksum mismatch for %s"] $distfile]"
    106                 } else {
    107                         continue
     144                ## XYZZY: as I look at this again, I'm thinking maybe we're doing
     145                ## it backwards - rather than calculate the checksum then go look for
     146                ## it, we should find the checksums we do have, then calculate those
     147                ## and compare, and note our successes.  We can then show those
     148                ## checksum types we know about that were not in the Portfile, and
     149                ## make mention of it.
     150                foreach chksum_type [array names checksum_types] {
     151                        # Find the expected checksum.
     152                        set dchecksum [get_checksum $distfile $chksum_type $port_checksums]
     153
     154                        # Check for missing checksum
     155                        if {$dchecksum == -1} {
     156                                ui_info "$UI_PREFIX [format [msgcat::mc "No %s checksum set for %s"] $chksum_type $distfile]"
     157                                ## and lets try the next one...
     158                                continue
     159                        }
     160                        ## sanity check - Do we actually have checksum routine?
     161                        if {[string length [info commands $checksum_types($chksum_type)]]} {
     162                                # Calculate the distfile's checksum.
     163                                set checksum [$checksum_types($chksum_type) file [file join [option distpath] $distfile]]
     164                        } else {
     165                                ## explode catch fire?  Just throw a warning and continue? Hmmm.
     166                                ui_error "$UI_PREFIX [format [msgcat::mc "Can't find checksum routine '%s' for checksum type '%s'"] $checksum_types($chksum_type) $chksum_type]"
     167                                continue
     168                        }
     169
     170                        # Check for checksum mismatch.
     171                        if {![string equal $checksum $dchecksum]} {
     172                                ui_error "$UI_PREFIX [format [msgcat::mc "%s checksum mismatch for '%s':"] $chksum_type $distfile]"
     173                                ui_error "$UI_PREFIX [format [msgcat::mc "wanted '%s',"] $dchecksum]"
     174                                ui_error "$UI_PREFIX [format [msgcat::mc "   got '%s'"] $checksum]"
     175                                # Raise the failure flag
     176                                set fail yes
     177                        } else {
     178                                set distfile_chksum_success [expr $distfile_chksum_success + 1]
     179                        }
     180       
     181                        if {[tbool fail]} {
     182                                return -code error "[format [msgcat::mc "Unable to verify %s checksum"] $chksum_type]"
     183                        }
     184                        ## else just fall to the next checksum...
     185       
     186                        if {$dchecksum != -1} {
     187                                # Post file checksum
     188                                ui_info "$UI_PREFIX [format [msgcat::mc "Correct %s checksum: %s %s %s"] $chksum_type ${distfile} $chksum_type ${checksum}]"
     189                        }
    108190                }
    109191
    110                 # Post file checksum
    111                 ui_info "[format [msgcat::mc "Correct checksum: %s %s %s"] ${distfile} md5 ${checksum}]"
    112 
    113                 # Raise the failure flag
    114                 set fail yes
    115         }
    116 
    117         if {[tbool fail]} {
    118                 return -code error "[msgcat::mc "Unable to verify file checksums"]"
     192                if {$distfile_chksum_success == 0} {
     193                        ## oh bother, no successful checksum for this dist file, bailage
     194                        return -code error "[format [msgcat::mc "No checksums set for %s"] $distfile]"
     195                }
    119196        }
    120197
    121198        return 0