#!/bin/sh # # $NetBSD: checksum,v 1.12 2007/08/15 13:56:24 jlam Exp $ # # Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation # by Johnny C. Lam. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by the NetBSD # Foundation, Inc. and its contributors. # 4. Neither the name of The NetBSD Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ###################################################################### # # NAME # checksum -- checksum files # # SYNOPSIS # checksum [options] distinfo [file ...] # # DESCRIPTION # checksum will verify the checksums in the distinfo file for each # of the files specified. # # The checksum utility exits with one of the following values: # # 0 All of the file checksums verify. # # 1 At least one of the file checksums did not match. # # 2 At least one of the files is missing any checksum. # # >2 An error occurred. # # OPTIONS # -a algorithm Only verify checksums for the specified algorithm. # # -p The specified files are patches, so strip out any # lines containing NetBSD RCS ID tags before # computing the checksums for verification. # # -s suffix Strip the specified suffix from the file names # when searching for the checksum. # ###################################################################### set -e # exit on errors : ${DIGEST:=digest} : ${CAT:=cat} : ${ECHO:=echo} : ${SED:=sed} : ${TEST:=test} self="${0##*/}" usage() { ${ECHO} 1>&2 "usage: $self [-a algorithm] [-p] [-s suffix] distinfo [file ...]" } # Process optional arguments algorithm= patch= suffix= while ${TEST} $# -gt 0; do case "$1" in -a) algorithm="$2"; shift 2 ;; -p) patch=yes; shift ;; -s) suffix="$2"; shift 2 ;; --) shift; break ;; -*) ${ECHO} 1>&2 "$self: unknown option -- ${1#-}" usage exit 128 ;; *) break ;; esac done # Process required arguments ${TEST} $# -gt 0 || { usage; exit 128; } distinfo="$1"; shift files="$@" files_left="$@" if ${TEST} ! -f "$distinfo"; then ${ECHO} 1>&2 "$self: distinfo file missing: $distinfo" exit 128 fi digestcmd= case "${DIGEST}" in /*) if ${TEST} -x "${DIGEST}"; then digestcmd="${DIGEST}" fi ;; *) SAVEIFS="$IFS"; IFS=: for i in $PATH; do if ${TEST} -x "$i/${DIGEST}"; then digestcmd="$i/${DIGEST}" break fi done IFS="$SAVEIFS" ;; esac if ${TEST} -z "$digestcmd"; then ${ECHO} 1>&2 "$self: \`\`${DIGEST}'' is missing" exit 128 fi { exitcode=0 while read d_alg d_file d_equals d_checksum; do case "$d_alg" in "#"*) continue ;; # skip comments "\$"*) continue ;; # skip RCS ID "") continue ;; # skip empty lines Size) continue ;; # skip lines holding filesizes, not checksums esac if ${TEST} -n "$algorithm"; then ${TEST} "$d_alg" = "$algorithm" || continue fi for file in $files; do sfile="${file%$suffix}" ${TEST} -z "$patch" || sfile="${sfile##*/}" ${TEST} "$d_file" = "($sfile)" || continue case "$files_left" in "$file"|"$file "*) pre= ;; *" $file") pre="${files_left%% $file}" ;; *) pre="${files_left%% $file *} " ;; esac case "$files_left" in "$file"|*" $file") post= ;; "$file "*) post="${files_left##$file }" ;; *) post="${files_left##* $file }" ;; esac files_left="${pre}${post}" if ${TEST} "$d_checksum" = "IGNORE"; then ${ECHO} 1>&2 "$self: Ignoring checksum for $sfile" continue fi if ${TEST} ! -f $file; then ${ECHO} 1>&2 "$self: $file does not exist" exit 128 fi if ${TEST} -z "$patch"; then checksum=`${DIGEST} $d_alg < $file` else checksum=`${SED} -e '/[$]NetBSD.*/d' $file | ${DIGEST} $d_alg` fi if ${TEST} "$d_checksum" = "$checksum"; then ${ECHO} "=> Checksum $d_alg OK for $sfile" else ${ECHO} 1>&2 "$self: Checksum $d_alg mismatch for $sfile" exit 1 fi break done done if ${TEST} -n "$files_left"; then for file in $files_left; do if ${TEST} -n "$algorithm"; then ${ECHO} 1>&2 "$self: No $algorithm checksum recorded for $file" else ${ECHO} 1>&2 "$self: No checksum recorded for $file" fi exitcode=2 done fi exit $exitcode; } < $distinfo